- 相關(guān)推薦
c語(yǔ)言面試常見(jiàn)問(wèn)題
1.const意味著”只讀",下面的聲明都是什么意思?
const int a;
int const a;
const int *a;
int * const a;
int const * a const;
前兩個(gè)的作用是一樣,a是一個(gè)常整型數(shù)。第三個(gè)意味著a是一個(gè)指向常整型數(shù)的指針(也就是,整型數(shù)是不可修改的,但指針可以)。第四個(gè)意思a是一個(gè)指向整型數(shù)的常指針(也就是說(shuō),指針指向的整型數(shù)是可以修改的,但指針是不可修改的)。最后一個(gè)意味著a是一個(gè)指向常整型數(shù)的常指針(也就是說(shuō),指針指向的整型數(shù)是不可修改的,同時(shí)指針也是不可修改的)。
結(jié)論:·;關(guān)鍵字const的作用是為給讀你代碼的人傳達(dá)非常有用的信息,實(shí)際上,聲明一個(gè)參數(shù)為常量是為了告訴了用戶這個(gè)參數(shù)的應(yīng)用目的。如果你曾花很多時(shí)間清理其它人留下的垃圾,你就會(huì)很快學(xué)會(huì)感謝這點(diǎn)多余的信息。(當(dāng)然,懂得用const的程序員很少會(huì)留下的垃圾讓別人來(lái)清理的。) ·;通過(guò)給優(yōu)化器一些附加的信息,使用關(guān)鍵字const也許能產(chǎn)生更緊湊的代碼。 ·;合理地使用關(guān)鍵字const可以使編譯器很自然地保護(hù)那些不希望被改變的參數(shù),防止其被無(wú)意的代碼修改。簡(jiǎn)而言之,這樣可以減少bug的出現(xiàn)。
(1)欲阻止一個(gè)變量被改變,可以使用const關(guān)鍵字。在定義該const變量時(shí),通常需要對(duì)它進(jìn)行初始化,因?yàn)橐院缶蜎](méi)有機(jī)會(huì)再去改變它了;
(2)對(duì)指針來(lái)說(shuō),可以指定指針本身為const,也可以指定指針?biāo)傅臄?shù)據(jù)為const,或二者同時(shí)指定為const;
(3)在一個(gè)函數(shù)聲明中,const可以修飾形參,表明它是一個(gè)輸入?yún)?shù),在函數(shù)內(nèi)部不能改變其值;
(4)對(duì)于類(lèi)的成員函數(shù),若指定其為const類(lèi)型,則表明其是一個(gè)常函數(shù),不能修改類(lèi)的成員變量;
(5)對(duì)于類(lèi)的成員函數(shù),有時(shí)候必須指定其返回值為const類(lèi)型,以使得其返回值不為“左值”。
2.關(guān)鍵字volatile有什么含意?并給出三個(gè)不同的例子。
一個(gè)定義為volatile的變量是說(shuō)這變量可能會(huì)被意想不到地改變,這樣,編譯器就不會(huì)去假設(shè)這個(gè)變量的值了。精確地說(shuō)就是,優(yōu)化器在用到這個(gè)變量時(shí)必須每次都小心地重新讀取這個(gè)變量的值,而不是使用保存在寄存器里的備份。下面是volatile變量的幾個(gè)例子:
(1)并行設(shè)備的硬件寄存器(如:狀態(tài)寄存器)
(2)一個(gè)中斷服務(wù)子程序中會(huì)訪問(wèn)到的非自動(dòng)變量(non-automatic variables)
(3)多線程應(yīng)用中被幾個(gè)任務(wù)共享的變量
3.一個(gè)參數(shù)既可以是const還可以是volatile嗎?解釋為什么。一個(gè)指針可以是volatile 嗎?解釋為什么。
答案:
(1)是的。一個(gè)例子是只讀的狀態(tài)寄存器。它是volatile因?yàn)樗赡鼙灰庀氩坏降馗淖。它是const因?yàn)槌绦虿粦?yīng)該試圖去修改它。
(2)是的。盡管這并不很常見(jiàn)。一個(gè)例子是當(dāng)一個(gè)中服務(wù)子程序修該一個(gè)指向一個(gè)buffer的指針時(shí)。
4.static關(guān)鍵字有什么作用?
(1)函數(shù)體內(nèi)static變量的作用范圍為該函數(shù)體,不同于auto變量,該變量的內(nèi)存只被分配一次,因此其值在下次調(diào)用時(shí)仍維持上次的值;
(2)在模塊內(nèi)的static全局變量可以被模塊內(nèi)所用函數(shù)訪問(wèn),但不能被模塊外其它函數(shù)訪問(wèn);
(3)在模塊內(nèi)的static函數(shù)只可被這一模塊內(nèi)的其它函數(shù)調(diào)用,這個(gè)函數(shù)的使用范圍被限制在聲明它的模塊內(nèi);
(4)在類(lèi)中的static成員變量屬于整個(gè)類(lèi)所擁有,對(duì)類(lèi)的所有對(duì)象只有一份拷貝;
(5)在類(lèi)中的static成員函數(shù)屬于整個(gè)類(lèi)所擁有,這個(gè)函數(shù)不接收this指針,因而只能訪問(wèn)類(lèi)的static成員變量。
5. extern 在"c"中有什么作用:
(1)被extern "c"限定的函數(shù)或變量是extern類(lèi)型的;
extern是c/c++語(yǔ)言中表明函數(shù)和全局變量作用范圍(可見(jiàn)性)的關(guān)鍵字,該關(guān)鍵字告訴編譯器,其聲明的函數(shù)和變量可以在本模塊或其它模塊中使用。
(2)被extern "c"修飾的變量和函數(shù)是按照c語(yǔ)言方式編譯和連接的;
extern "c"的慣用法
(1)在c++中引用c語(yǔ)言中的函數(shù)和變量,在包含c語(yǔ)言頭文件(假設(shè)為cexample.h)時(shí),需進(jìn)行下列處理:
extern "c" { #include"cexample.h" }
《c語(yǔ)言面試常見(jiàn)問(wèn)題》全文內(nèi)容當(dāng)前網(wǎng)頁(yè)未完全顯示,剩余內(nèi)容請(qǐng)?jiān)L問(wèn)下一頁(yè)查看。
而在c語(yǔ)言的頭文件中,對(duì)其外部函數(shù)只能指定為extern類(lèi)型,c語(yǔ)言中不支持extern "c"聲明,在.c文件中包含了extern "c"時(shí)會(huì)出現(xiàn)編譯語(yǔ)法錯(cuò)誤。
(2)在c中引用c++語(yǔ)言中的函數(shù)和變量時(shí),c++的頭文件需添加extern "c",但是在c語(yǔ)言中不能直接引用聲明了extern "c"的該頭文件,應(yīng)該僅將c文件中將c++中定義的extern "c"函數(shù)聲明為extern類(lèi)型。
6. 堆和棧的區(qū)別?
管理方式:對(duì)于棧來(lái)講,是由編譯器自動(dòng)管理,無(wú)需我們手工控制;對(duì)于堆來(lái)說(shuō),釋放工作由程序員控制,容易產(chǎn)生memory leak。
申請(qǐng)大小:棧:棧是向低地址擴(kuò)展的數(shù)據(jù)結(jié)構(gòu),是一塊連續(xù)的內(nèi)存的區(qū)域
堆:是向高地址擴(kuò)展的數(shù)據(jù)結(jié)構(gòu),是不連續(xù)的內(nèi)存區(qū)域。
分配方式:堆都是動(dòng)態(tài)分配的,動(dòng)態(tài)分配由alloca函數(shù)進(jìn)行分配
棧的動(dòng)態(tài)分配由編譯器進(jìn)行釋放,無(wú)需我們手工實(shí)現(xiàn)
7.以下函數(shù)輸出結(jié)果是
main()
{ int a[5]={1,2,3,4,5};
int *ptr=(int *)(&a+1);
printf("%d,%d",*(a+1),*(ptr-1));
}
答:2,5 *(a+1)就是a[1],*(ptr-1)就是a[4],執(zhí)行結(jié)果是2,5
&a+1不是首地址+1,系統(tǒng)會(huì)認(rèn)為加一個(gè)a數(shù)組的偏移,是偏移了一個(gè)數(shù)組的大小(本例是5個(gè)int)
int *ptr=(int *)(&a+1);則ptr實(shí)際是&(a[5]),也就是a+5
原因如下:&a是數(shù)組指針,其類(lèi)型為int (*)[5];
而指針加1要根據(jù)指針類(lèi)型加上一定的值,不同類(lèi)型的指針+1之后增加的大小不同。
a是長(zhǎng)度為5的int數(shù)組指針,所以要加5*sizeof(int),所以ptr實(shí)際是a[5],
但是prt與(&a+1)類(lèi)型是不一樣的(這點(diǎn)很重要),所以prt-1只會(huì)減去sizeof(int*)
a,&a的地址是一樣的,但意思不一樣
a是數(shù)組首地址,也就是a[0]的地址,&a是對(duì)象(數(shù)組)首地址,
a+1是數(shù)組下一元素的地址,即a[1],&a+1是下一個(gè)對(duì)象的地址,即a[5].
8.鏈表和數(shù)組的區(qū)別在哪里?
二者都屬于一種數(shù)據(jù)結(jié)構(gòu)
從邏輯結(jié)構(gòu)來(lái)看
1.數(shù)組必須事先定義固定的長(zhǎng)度(元素個(gè)數(shù)),不能適應(yīng)數(shù)據(jù)動(dòng)態(tài)地增減的情況。當(dāng)數(shù)據(jù)增加時(shí),可能超出原先定義的元素個(gè)數(shù);當(dāng)數(shù)據(jù)減少時(shí),造成內(nèi)存浪費(fèi);數(shù)組可以根據(jù)下標(biāo)直接存取。
2.鏈表動(dòng)態(tài)地進(jìn)行存儲(chǔ)分配,可以適應(yīng)數(shù)據(jù)動(dòng)態(tài)地增減的情況,且可以方便地插入、刪除數(shù)據(jù)項(xiàng)。(數(shù)組中插入、刪除數(shù)據(jù)項(xiàng)時(shí),需要移動(dòng)其它數(shù)據(jù)項(xiàng),非常繁瑣)鏈表必須根據(jù)next指針找到下一個(gè)元素
從內(nèi)存存儲(chǔ)來(lái)看
1. (靜態(tài))數(shù)組從棧中分配空間,對(duì)于程序員方便快速,但是自由度小
2.鏈表從堆中分配空間,自由度大但是申請(qǐng)管理比較麻煩
從上面的比較可以看出,如果需要快速訪問(wèn)數(shù)據(jù),很少或不插入和刪除元素,就應(yīng)該用數(shù)組;相反,如果需要經(jīng)常插入和刪除元素就需要用鏈表數(shù)據(jù)結(jié)構(gòu)了。
9.結(jié)構(gòu)體
struct stra { int a; float b; char c; }expa;
printf("%ld",sizeof(expa));
輸出結(jié)果為12 ?
該問(wèn)題涉及編譯器的“內(nèi)存對(duì)齊”問(wèn)題:
現(xiàn)代計(jì)算機(jī)中內(nèi)存空間都是按照byte(字節(jié))劃分的,從理論上講似乎對(duì)任何類(lèi)型的變量的訪問(wèn)可以從任何地址開(kāi)始,但實(shí)際情況是在訪問(wèn)特定變量的時(shí)候經(jīng)常在特定的內(nèi)存地址訪問(wèn),這就需要各類(lèi)型數(shù)據(jù)按照一定的規(guī)則在空間上排列,而不是順序的一個(gè)接一個(gè)的排放,這就是對(duì)齊。
對(duì)齊的作用和原因:各個(gè)硬件平臺(tái)對(duì)存儲(chǔ)空間的處理上有很大的不同。一些平臺(tái)對(duì)某些特定類(lèi)型的數(shù)據(jù)只能從某些特定地址開(kāi)始存取。其他平臺(tái)可能沒(méi)有這種情況,
但是最常見(jiàn)的是如果不按照適合其平臺(tái)的要求對(duì)數(shù)據(jù)存放進(jìn)行對(duì)齊,會(huì)在存取效率上帶來(lái)?yè)p失。比如有些平臺(tái)每次讀都是從偶地址開(kāi)始,如果一個(gè)int型(假設(shè)為32位)如果存放在偶地址開(kāi)始的地方,那么一個(gè)讀周期就可以讀出,而如果存放在奇地址開(kāi)始的地方,就可能會(huì)需要2個(gè)讀周期,并對(duì)兩次讀出的結(jié)果的高低
字節(jié)進(jìn)行拼湊才能得到該int數(shù)據(jù)。顯然在讀取效率上下降很多。這也是空間和時(shí)間的博弈。
通常,我們寫(xiě)程序的時(shí)候,不需要考慮對(duì)齊問(wèn)題。編譯器會(huì)替我們選擇適合目標(biāo)平臺(tái)的對(duì)齊策略。當(dāng)然,我們也可以通知給編譯器傳遞預(yù)編譯指令而改變對(duì)指定數(shù)據(jù)的對(duì)齊方法。
但是,正因?yàn)槲覀円话悴恍枰P(guān)心這個(gè)問(wèn)題,所以因?yàn)榫庉嬈鲗?duì)數(shù)據(jù)存放做了對(duì)齊,而我們不了解的話,常常會(huì)對(duì)一些問(wèn)題感到迷惑。最常見(jiàn)的就是struct數(shù)據(jù)結(jié)構(gòu)的sizeof結(jié)果,出乎意料。
對(duì)于結(jié)構(gòu)體來(lái)說(shuō),按成員中所占字節(jié)最大的是float類(lèi)型,占用4個(gè)字節(jié),一共有3個(gè)成員,所以總的占用字節(jié)為:4* 3 = 12.
【c語(yǔ)言面試常見(jiàn)問(wèn)題】相關(guān)文章:
c 面試常見(jiàn)問(wèn)題11-25
c語(yǔ)言心得05-17
怎樣學(xué)習(xí)c++c語(yǔ)言編程04-28
面試 常見(jiàn)問(wèn)題11-25
面試經(jīng)典常見(jiàn)問(wèn)題11-25
精選面試常見(jiàn)問(wèn)題11-25
面試常見(jiàn)問(wèn)題12-02
軟考程序員輔導(dǎo):程序員C語(yǔ)言新人常見(jiàn)問(wèn)題02-03
C語(yǔ)言跳出循環(huán)10-16