當(dāng)前位置:高考升學(xué)網(wǎng) > 招聘筆試題 > 正文
67.
#include
#include
int modifyvalue()
{
int x;
return(x+=10);
}
int changevalue(int x)
{
x+=1;
return(x);
}
int main(int argc,charargv[])
{
int x=10;
x++;
x=changevalue(x);
printf("changevalue:%d\n",x);//12
x++;
modifyvalue();
printf("Firstoutput:%d\n",x);//13
x++;
x=changevalue(x);//15
printf("Secondoutput:%d\n",x);
modifyvalue();
printf("Thirdoutput:%d\n",x);//15
return 1;
}
int modifyvalue()
{
int x;
return(x+=10);
}
int changevalue(int x)
{
x+=1;
return(x);
}
int main(int argc,charargv[])
{
int x=10;
x++;
changevalue(x);//變量沒(méi)有接受返回值
printf("changevalue:%d\n",x);//11
x++;
modifyvalue(); //無(wú)形參
printf("Firstoutput:%d\n",x);//12
x++;
changevalue(x);//15
printf("Secondoutput:%d\n",x);//13
modifyvalue();
printf("Thirdoutput:%d\n",x);//13
return 1;
}
考查臨時(shí)變量(返回值為棧中變量)的生存期:僅僅在于 緊跟著的一條語(yǔ)句;
73、下面的代碼輸出是什么,為什么?
void foo(void)
{
unsigned inta = 6;
int b = -20;
(a+b> 6)? puts("> 6") : puts("<= 6");
}
【參考答案】這個(gè)問(wèn)題測(cè)試你是否懂得C語(yǔ)言中的整數(shù)自動(dòng)轉(zhuǎn)換原則,
我發(fā)現(xiàn)有些開發(fā)者懂得極少這些東西。不管如何,這無(wú)符號(hào)整型問(wèn)題的答案是輸出是“>6”。
原因是當(dāng)表達(dá)式中存在有符號(hào)類型和無(wú)符號(hào)類型時(shí)所有的數(shù)都自動(dòng)轉(zhuǎn)換為無(wú)符號(hào)類型。
因此-20變成了一個(gè)非常大的正整數(shù),所以該表達(dá)式計(jì)算出的結(jié)果大于6。
這一點(diǎn)對(duì)于應(yīng)當(dāng)頻繁用到無(wú)符號(hào)數(shù)據(jù)類型的嵌入式系統(tǒng)來(lái)說(shuō)是豐常重要的
74、評(píng)價(jià)下面的代碼片斷:
unsigned intzero = 0;
unsigned intcompzero= 0xFFFF;
/1‘s complement of zero /
【參考答案】對(duì)于一個(gè)int型不是16位的處理器為說(shuō),上面的代碼是不正
確的。應(yīng)編寫如下:
unsigned intcompzero= ~0;
這一問(wèn)題真正能揭露出應(yīng)試者是否懂得處理器字長(zhǎng)的重要性。在我的經(jīng)
驗(yàn)里,好的嵌入式程序員非常準(zhǔn)確地明白硬件的細(xì)節(jié)和它的局限,然而
PC機(jī)程序往往把硬件作為一個(gè)無(wú)法避免的煩惱。
75.
char ptr;
if ((ptr= (char )malloc(0)) ==NULL)
puts("Gota nullpointer");
else
puts("Gota validpointer");
如果所請(qǐng)求的空間大小為0,其行為由庫(kù)的實(shí)現(xiàn)者定義:可以返回空指針,也可以讓效果跟申某個(gè)非0大小的空間一樣,所不同的是返回的指針不可以被用來(lái)訪問(wèn)一個(gè)對(duì)象。
為什么 new T[0] 和 malloc(0) 不返回空指針
首先需要說(shuō)明的是,按照C++標(biāo)準(zhǔn),成功的 new T[0] 是不能返回空指針的。而 malloc(0),C 語(yǔ)言標(biāo)準(zhǔn)則指出,成功的時(shí)候可以返回空指針,也可以返回非空指針,多數(shù)庫(kù)一般也選擇了返回非空指針這種行為。
76.
int main(int argc,char argv[])
{
char a='a',b='b';
int p,c,d;
p=a;
p=(p<<8)|b;
d=p&0xff;
c=(p&0xff00)>>8;
printf("a=%d\nb=%d\nc=%d\nd=%d\n",a,b,c,d);
return 1;
}
[運(yùn)行結(jié)果]:97,98,97,98
77.
int main(int argc,char argv[])
{
unsigned a,b;
printf("please input a number:");
scanf("%d",&a);
b=a>>5;
b=b&15;
printf("a=%d\tb=%d\n",a,b);
return 1;
}
【運(yùn)行結(jié)果】:輸入 64,輸出2
概念區(qū)別
指針數(shù)組:存放指針的數(shù)組;
Int ptr[4]; (等同于二級(jí)指針 int ptr)
一級(jí)指針是指向定義類型的內(nèi)存地址,二級(jí)指針就是指向定義類型的內(nèi)存地址所指向的新的內(nèi)存地址
應(yīng)用:指向若干字符串,整形數(shù)據(jù)等,使得元素處理更加方便;其中元素存放各對(duì)應(yīng)地址;
此時(shí),一級(jí)指針只能尋址到字符串所在的位置,并不能將其輸出,因?yàn)闆](méi)有其首地址,而p則完成二級(jí)尋址,找到了位置,也找到了它的首地址,所以能輸出
數(shù)組指針:指向一個(gè)數(shù)組的指針;
Int (ptr)[4]
應(yīng)用:可以應(yīng)用在二維數(shù)組中;
指針函數(shù):返回指針值得函數(shù)
Int search(int num);
函數(shù)指針:指向函數(shù)的指針
Int (ptr)(int num);/申明一個(gè)函數(shù)指針/
Ptr=fun();/將fun函數(shù)地址付給指針ptr/
Int a=fun(6).等價(jià)于,int a=(ptr)(6);
函數(shù)指針數(shù)組:int(s[10])(int) 函數(shù)指針數(shù)組
27、關(guān)鍵字volatile有什么含意?并給出三個(gè)不同的例子。
它是用來(lái)修飾被不同線程訪問(wèn)和修改的變量。
如果沒(méi)有volatile,基本上會(huì)導(dǎo)致:要么無(wú)法編寫多線程程序,要么編譯器失去大量?jī)?yōu)化的機(jī)會(huì)。volatile的變量是說(shuō)這變量可能會(huì)被意想不到地改變,這樣,編譯器就不會(huì)去假設(shè)這個(gè)變量的值了。精確地說(shuō)就是,優(yōu)化器在用到這個(gè)變量時(shí)必須每次都小心地重新讀取這個(gè)變量的值,而不是使用保存在寄存器里的備份。下面是volatile變量的幾個(gè)例子:
1). 并行設(shè)備的硬件寄存器(如:狀態(tài)寄存器)
存儲(chǔ)器映射的硬件寄存器通常也要加volatile說(shuō)明,因?yàn)槊看螌?duì)它的讀寫都可能由不同意義;
2). 一個(gè)中斷服務(wù)子程序中會(huì)訪問(wèn)到的非自動(dòng)變量(Non-automatic variables)
中斷服務(wù)程序中修改的供其它程序檢測(cè)的變量需要加volatile;
3). 多線程應(yīng)用中被幾個(gè)任務(wù)共享的變量
多任務(wù)環(huán)境下各任務(wù)間共享的標(biāo)志應(yīng)該加volatile
3個(gè)關(guān)聯(lián)的問(wèn)題:
1). 一個(gè)參數(shù)既可以是const還可以是volatile嗎?解釋為什么。
2). 一個(gè)指針可以是volatile 嗎?解釋為什么。
3). 下面的函數(shù)有什么錯(cuò)誤:
int square(volatile int ptr)
{
return ptr ptr;
}
下面是答案:
1). 是的。一個(gè)例子是只讀的狀態(tài)寄存器。它是volatile因?yàn)樗赡鼙灰庀氩坏降馗淖。它是const因?yàn)槌绦虿粦?yīng)該試圖去修改它。
2). 是的。盡管這并不很常見(jiàn)。一個(gè)例子是當(dāng)一個(gè)中服務(wù)子程序修該一個(gè)指向一個(gè)buffer的指針時(shí)。
3). 這段代碼的有個(gè)惡作劇。這段代碼的目的是用來(lái)返指針ptr指向值的方,但是,由于ptr指向一個(gè)volatile型參數(shù),編譯器將產(chǎn)生類似下面的代碼:
int square(volatile int ptr)
{
int a,b;
a = ptr;
b = ptr;
return a b;
}
由于ptr的值可能被意想不到地該變,因此a和b可能是不同的。結(jié)果,這段代碼可能返不是你所期望的方值!正確的代碼如下:
long square(volatile int ptr)
{
int a;
a = ptr;
return a a;
}
37、Heap與stack的差別。
【標(biāo)準(zhǔn)答案】Heap是堆,stack是棧。
Stack的空間由操作系統(tǒng)自動(dòng)分配/釋放,Heap上的空間手動(dòng)分配/放。
Stack空間有限,Heap是很大的自由存儲(chǔ)區(qū)
C中的malloc函數(shù)分配的內(nèi)存空間即在堆上,C++中對(duì)應(yīng)的是new操符。
程序在編譯期對(duì)變量和函數(shù)分配內(nèi)存都在棧上進(jìn)行,且程序運(yùn)行過(guò)程中函數(shù)調(diào)用時(shí)參數(shù)的傳遞也在棧上進(jìn)行
40、帶參宏與帶參函數(shù)的區(qū)別(至少說(shuō)出5點(diǎn))?
帶參宏 帶參函數(shù)
處理時(shí)間:編譯時(shí) 運(yùn)行時(shí)
參數(shù)類型:無(wú) 定義類型
程序長(zhǎng)度:變長(zhǎng) 不變
占用存儲(chǔ)空間:否 是
運(yùn)行時(shí)間:不占用 調(diào)用和返回占用時(shí)間
38.用宏定義寫出swap(x,y),即交換兩數(shù)
#define swap(x, y) (x)=(x)+(y);(y)=(x)–(y);(x)=(x)–(y);
39. 寫一個(gè)“標(biāo)準(zhǔn)”宏,這個(gè)宏輸入兩個(gè)參數(shù)并返回較小的一個(gè)。
#define Min(X, Y) ((X)>(Y)?(Y):(X)) //結(jié)尾沒(méi)有;
43、已知一個(gè)數(shù)組table,用一個(gè)宏定義,求出數(shù)據(jù)的元素個(gè)數(shù)。
【標(biāo)準(zhǔn)答案】#define NTBL(table) (sizeof(table)/sizeof(table[0]))
1. 用預(yù)處理指令#define 聲明一個(gè)常數(shù),用以表明1年中有多少秒(忽略閏年問(wèn)題)
#define SECONDS_PER_YEAR (60 60 24 365)UL
總結(jié):有關(guān)宏定義#define 的基本語(yǔ)法
1#define的概念
#define命令是C語(yǔ)言中的一個(gè)宏定義命令,它用來(lái)將一個(gè)標(biāo)識(shí)符定義為一個(gè)字符串,該標(biāo)識(shí)符被稱為宏名,被定義的字符串稱為替換文本。
該命令有兩種格式:一種是簡(jiǎn)單的宏定義,另一種是帶參數(shù)的宏定義。
(1) 簡(jiǎn)單的宏定義:
#define <宏名> <字符串>
例:#define PI 3.1415926
(2) 帶參數(shù)的宏定義
#define <宏名>(<參數(shù)表>) <宏體>
例:#defineA(x) x
一個(gè)標(biāo)識(shí)符被宏定義后,該標(biāo)識(shí)符便是一個(gè)宏名。
這時(shí),在程序中出現(xiàn)的是宏名,在該程序被編譯前,先將宏名用被定義的字符串替換,這稱為宏替換,替換后才進(jìn)行編譯,宏替換是簡(jiǎn)單的替換。
2.宏定義的缺點(diǎn)
在簡(jiǎn)單宏定義的使用中,當(dāng)替換文本所表示的字符串為一個(gè)表達(dá)式時(shí),容易引起誤解和誤用。如下例:
例1 #define N 2+2
void main()
{
int a=NN;
printf(“%d”,a);
}
(1) 出現(xiàn)問(wèn)題:在此程序中存在著宏定義命令,宏N代表的字符串是2+2,該題的結(jié)果為8,
(2) 問(wèn)題解析:宏展開是在預(yù)處理階段完成的,這個(gè)階段把替換文本只是看作一個(gè)字符串,并不會(huì)有任何的計(jì)算發(fā)生,在展開時(shí)是在宏N出現(xiàn)的地方只是簡(jiǎn)單地使用串2+2來(lái)代替N,并不會(huì)增添任何的符號(hào),所以對(duì)該程序展開后的結(jié)果是a=2+22+2,計(jì)算后=8,這就是宏替換的實(shí)質(zhì),如何寫程序才 能完成結(jié)果為16的運(yùn)算呢?
(3)解決辦法:將宏定義寫成如下形式
#define N (2+2)
這樣就可替換成(2+2)(2+2)=16
在帶參數(shù)的宏定義的使用中,極易引起誤解。例如我們需要做個(gè)宏替換能求任何數(shù)的方,這就需要使用參數(shù),以便在程序中用實(shí)際參數(shù)來(lái)替換宏定義中的參數(shù)。一般學(xué)生容易寫成如下形式:
#define area(x) xx
這在使用中是很容易出現(xiàn)問(wèn)題的,看如下的程序
void main()
{
int y=area(2+2);
printf(“%d”,y);
}
按 理說(shuō)給的參數(shù)是2+2,所得的結(jié)果應(yīng)該為44=16,但是錯(cuò)了,因?yàn)樵摮绦虻膶?shí)際結(jié)果為8,仍然是沒(méi)能遵循純粹的簡(jiǎn)單替換的規(guī)則,又是先計(jì)算再替換了,在這道程序里,2+2即為area宏中的參數(shù),應(yīng)該由它來(lái)替換宏定義中的x,即替換成2+22+2=8了。那如果遵循(1)中的解決辦法,把2+2 括起來(lái),即把宏體中的x括起來(lái),是否可以呢?#define area(x) (x)(x),對(duì)于area(2+2),替換為(2+2)(2+2)=16,可以解決,但是對(duì)于area(2+2)/area(2+2)又會(huì)怎么樣 呢,這道題替換后會(huì)變?yōu)?(2+2)(2+2)/(2+2)(2+2)即44/44按照乘除運(yùn)算規(guī)則,結(jié)果為16/44=44=16,那應(yīng)該怎么呢?解決方法是在整個(gè)宏體上再加一個(gè)括號(hào),即
#define area(x) ((x)(x)),不要覺(jué)得這沒(méi)必要,沒(méi)有它,是不行的。
要想能夠真正使用好宏 定義,
一定要記住先將程序中對(duì)宏的使用全部替換成它所代表的字符串,不要自作主張地添加任何其他符號(hào),完全展開后再進(jìn)行相應(yīng)的計(jì)算,就不會(huì)寫錯(cuò)運(yùn)行結(jié)果。
如果是自己編程使用宏替換,則在使用簡(jiǎn)單宏定義時(shí),當(dāng)字符串中不只一個(gè)符號(hào)時(shí),加上括號(hào)表現(xiàn)出優(yōu)先級(jí),如果是 帶參數(shù)的宏定義,則要給宏體中的每個(gè)參數(shù)加上括號(hào),并在整個(gè)宏體上再加一個(gè)括號(hào)。
宏定義的優(yōu)點(diǎn):
(1) 方便程序的修改
使用簡(jiǎn)單宏定義可用宏代替一個(gè)在程序中經(jīng)常使用的常量,這樣在將該常量改變時(shí),不用對(duì)整個(gè)程序進(jìn)行修改,只修改宏定義的字符串即可,而且當(dāng)常量比較長(zhǎng)時(shí), 我們可以用較短的有意義的標(biāo)識(shí)符來(lái)寫程序,這樣更方便一些。
(2) 提高程序的運(yùn)行效率
使用帶參數(shù)的宏定義可完成函數(shù)調(diào)用的功能,又能 減少系統(tǒng)開 銷,提高運(yùn)行效率。正如C語(yǔ)言中所講,函數(shù)的使用可以使程序更加模塊化,便于組織,而且可重復(fù)利用,但在發(fā)生函數(shù)調(diào)用時(shí),需要保留調(diào)用函數(shù)的現(xiàn)場(chǎng),以便子函數(shù)執(zhí)行結(jié)束后能返回繼續(xù)執(zhí)行,同樣在子函數(shù)執(zhí)行完后要恢復(fù)調(diào)用函數(shù)的現(xiàn)場(chǎng),這都需要一定的時(shí)間,如果子函數(shù)執(zhí)行的操作比較多,這種轉(zhuǎn)換時(shí)間開銷可以忽略,但如果子函數(shù)完成的功能比較少,甚至于只完成一點(diǎn)操作,如一個(gè)乘法語(yǔ)句的操作,則這部分轉(zhuǎn)換開銷就相對(duì)較大了,但使用帶參數(shù)的宏定義就不會(huì)出現(xiàn)這個(gè)問(wèn)題,因?yàn)樗窃陬A(yù)處理階段即進(jìn)行了宏展開,在執(zhí)行時(shí)不需要轉(zhuǎn)換,即在當(dāng)?shù)貓?zhí)行。宏定義可完成簡(jiǎn)單的操作,但復(fù)雜的操作還是要由函數(shù)調(diào)用來(lái)完成,而且宏定義所占用的目標(biāo)代碼空間相對(duì)較大。所以在使用時(shí)要依據(jù)具體情況來(lái)決定是否使用宏定義。
49、什么是預(yù)編譯,何時(shí)需要預(yù)編譯:
【標(biāo)準(zhǔn)答案】1、總是使用不經(jīng)常改動(dòng)的大型代碼體
2、程序由多個(gè)模塊組成,所有模塊都使用一組標(biāo)準(zhǔn)的包含文件和相同的編譯選項(xiàng)。在這種情況下,可以將所有包含文件預(yù)編譯為一個(gè)預(yù)編譯頭。
53、Typedef在C語(yǔ)言中頻繁用以聲明一個(gè)已經(jīng)存在的數(shù)據(jù)類型的同義字。也可以用預(yù)處理器做類似的事。
如,思考一下下面的例子:
#define dPSstructs
typedefstructs tPS;
以上兩種情況的意圖都是要定義dPS和tPS作為一個(gè)指向結(jié)構(gòu)s指針。哪種方法更好呢?
答案是:typedef更好。思考下面的例子:
dPSp1,p2;
tPSp3,p4;
第一個(gè)擴(kuò)展為
structs p1, p2;
上面的代碼定義p1為一個(gè)指向結(jié)構(gòu)的指,p2為一個(gè)實(shí)際的結(jié)構(gòu),這也許
不是你想要的。第二個(gè)例子正確地定義了p3 和p4 兩個(gè)指針。
54.在C++ 程序中調(diào)用被C 編譯器編譯后的函數(shù),為什么要加extern “C”?
重點(diǎn)就是C++里面支持函數(shù)的重載,因此編譯出來(lái)的.obj或者庫(kù)文件里面,函數(shù)名會(huì)被加上和參數(shù)有關(guān)的簽名,用來(lái)區(qū)分同樣函數(shù)名參數(shù)不同的函數(shù)。然而C語(yǔ)言不支持重載,所以函數(shù)名里面沒(méi)有這樣的簽名。
這樣,當(dāng)C語(yǔ)言的程序調(diào)用C++寫成的庫(kù)的時(shí)候,就會(huì)找不到函數(shù)。比如,一個(gè)函數(shù)叫 void foo(int bar)之類的,可能會(huì)在c++編譯成叫 foo_i之類的名字,而在c語(yǔ)言里面就會(huì)編譯成foo,這樣c語(yǔ)言的程序去找foo就會(huì)找不到,這樣連接的時(shí)候會(huì)出錯(cuò)。
為了解決這個(gè)問(wèn)題,引入了extrn "c"{},在這個(gè)的作用域之內(nèi),c++的函數(shù)名不會(huì)加上參數(shù)簽名,和c語(yǔ)言的標(biāo)準(zhǔn)保持統(tǒng)一,就兼容c語(yǔ)言的程序了。
2、中斷是嵌入式系統(tǒng)中重要的組成部分,這導(dǎo)致了很多編譯開發(fā)商提供一種擴(kuò)展—讓標(biāo)準(zhǔn)C支持中斷。具代表事實(shí)是,產(chǎn)生了一個(gè)新的關(guān)鍵字__interrupt。下面的代碼就使用了__interrupt關(guān)鍵字去定義了一個(gè)中斷服務(wù)子程序(ISR),請(qǐng)?jiān)u論一下這段代碼的。
__interrupt double compute_area(double radius)
{
double area = PI radius radius;
printf(" Area = %f", area);
return area;
}
【參考答案】這個(gè)函數(shù)有太多的錯(cuò)誤了,以至讓人不知從何說(shuō)起了:
1). ISR 不能返回一個(gè)值。如果你不懂這個(gè),那么你不會(huì)被雇用的。
2). ISR 不能傳遞參數(shù)。如果你沒(méi)有看到這一點(diǎn),你被雇用的機(jī)會(huì)等同第
一項(xiàng)。
3). 在許多的處理器/編譯器中,浮點(diǎn)一般都是不可重入的。有些處理器/編
譯器需要讓額處的寄存器入棧,有些處理器/編譯器就是不允許在ISR中做
浮點(diǎn)運(yùn)算。此外,ISR應(yīng)該是短而有效率的,在ISR中做浮點(diǎn)運(yùn)算是不明
智的。
4). 與第三點(diǎn)一脈相承,printf()經(jīng)常有重入和性能上的問(wèn)題。如果你丟掉
了第三和第四點(diǎn),我不會(huì)太為難你的。
35、全局變量可不可以定義在可被多個(gè).C文件包含的頭文件中?為什么?
【標(biāo)準(zhǔn)答案】可以
2020年河北新聞網(wǎng)兩學(xué)一做
時(shí)間:2023-09-18 07:0:242020年河北新聞網(wǎng)兩學(xué)一做
時(shí)間:2023-09-15 11:0:59兩學(xué)一做學(xué)習(xí)教育知
時(shí)間:2023-09-21 06:0:302020年開展兩學(xué)一做學(xué)習(xí)教
時(shí)間:2023-09-19 21:0:30