基礎(chǔ)面試C知識(shí)_第1頁(yè)
基礎(chǔ)面試C知識(shí)_第2頁(yè)
基礎(chǔ)面試C知識(shí)_第3頁(yè)
基礎(chǔ)面試C知識(shí)_第4頁(yè)
基礎(chǔ)面試C知識(shí)_第5頁(yè)
已閱讀5頁(yè),還剩30頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、微軟亞洲技術(shù)中心的面試題!1進(jìn)程和線程的差別。線程是指進(jìn)程內(nèi)的一個(gè)執(zhí)行單元,也是進(jìn)程內(nèi)的可調(diào)度實(shí)體.與進(jìn)程的區(qū)別:(1)調(diào)度:線程作為調(diào)度和分配的基本單位,進(jìn)程作為擁有資源的基本單位(2)并發(fā)性:不僅進(jìn)程之間可以并發(fā)執(zhí)行,同一個(gè)進(jìn)程的多個(gè)線程之間也可并發(fā)執(zhí)行(3)擁有資源:進(jìn)程是擁有資源的一個(gè)獨(dú)立單位,線程不擁有系統(tǒng)資源,但可以訪問(wèn)隸屬于進(jìn)程的資源. (4)系統(tǒng)開(kāi)銷:在創(chuàng)建或撤消進(jìn)程時(shí),由于系統(tǒng)都要為之分配和回收資源,導(dǎo)致系統(tǒng)的開(kāi)銷明顯大于創(chuàng)建或撤消線程時(shí)的開(kāi)銷。2.測(cè)試方法 人工測(cè)試:個(gè)人復(fù)查、抽查和會(huì)審機(jī)器測(cè)試:黑盒測(cè)試和白盒測(cè)試6.軟件測(cè)試都有那些種類?黑盒:針對(duì)系統(tǒng)功能的測(cè)試 白合:測(cè)

2、試函數(shù)功能,各函數(shù)接口main()  int a5=1,2,3,4,5;   int *ptr=(int *)(&a+1);   printf("%d,%d",*(a+1),*(ptr-1);輸出:2,5*(a+1)就是a1,*(ptr-1)就是a4,執(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í)際是&(a5),也就是a+5原因如下:&a是數(shù)組指針,其類型為 in

3、t (*)5;而指針加1要根據(jù)指針類型加上一定的值,不同類型的指針+1之后增加的大小不同a是長(zhǎng)度為5的int數(shù)組指針,所以要加 5*sizeof(int)所以ptr實(shí)際是a5但是prt與(&a+1)類型是不一樣的(這點(diǎn)很重要)所以prt-1只會(huì)減去sizeof(int*)a,&a的地址是一樣的,但意思不一樣,a是數(shù)組首地址,也就是a0的地址,&a是對(duì)象(數(shù)組)首地址,a+1是數(shù)組下一元素的地址,即a1,&a+1是下一個(gè)對(duì)象的地址,即a5.解析C語(yǔ)言中的sizeof一、sizeof的概念 sizeof是C語(yǔ)言的一種單目操作符,如C語(yǔ)言的其他操作符+、-等。它并不是

4、函數(shù)。sizeof操作符以字節(jié)形式給出了其操作數(shù)的存儲(chǔ)大小。操作數(shù)可以是一個(gè)表達(dá)式或括在括號(hào)內(nèi)的類型名。操作數(shù)的存儲(chǔ)大小由操作數(shù)的類型決定。二、sizeof的使用方法 1、用于數(shù)據(jù)類型sizeof使用形式:sizeof(type)數(shù)據(jù)類型必須用括號(hào)括住。如sizeof(int)。2、用于變量sizeof使用形式:sizeof(var_name)或sizeofvar_name變量名可以不用括號(hào)括住。如sizeof(var_name),sizeofvar_name等都是正確形式。帶括號(hào)的用法更普遍,大多數(shù)程序員采用這種形式。注意:sizeof操作符不能用于函數(shù)類型,不完全類型或位字段。不完全類型指

5、具有未知存儲(chǔ)大小的數(shù)據(jù)類型,如未知存儲(chǔ)大小的數(shù)組類型、未知內(nèi)容的結(jié)構(gòu)或聯(lián)合類型、void類型等。如sizeof(max)若此時(shí)變量max定義為intmax(),sizeof(char_v)若此時(shí)char_v定義為charchar_vMAX且MAX未知,sizeof(void)都不是正確形式。三、sizeof的結(jié)果 sizeof操作符的結(jié)果類型是size_t,它在頭文件中typedef為unsignedint類型。該類型保證能容納實(shí)現(xiàn)所建立的最大對(duì)象的字節(jié)大小。1、若操作數(shù)具有類型char、unsignedchar或signedchar,其結(jié)果等于1。ANSIC正式規(guī)定字符類型為1字節(jié)。2、in

6、t、unsignedint、shortint、unsignedshort、longint、unsignedlong、float、double、longdouble類型的sizeof在ANSIC中沒(méi)有具體規(guī)定,大小依賴于實(shí)現(xiàn),一般可能分別為2、2、2、2、4、4、4、8、10。3、當(dāng)操作數(shù)是指針時(shí),sizeof依賴于編譯器。例如MicrosoftC/C+7.0中,near類指針字節(jié)數(shù)為2,far、huge類指針字節(jié)數(shù)為4。一般Unix的指針字節(jié)數(shù)為4。4、當(dāng)操作數(shù)具有數(shù)組類型時(shí),其結(jié)果是數(shù)組的總字節(jié)數(shù)。5、聯(lián)合類型操作數(shù)的sizeof是其最大字節(jié)成員的字節(jié)數(shù)。結(jié)構(gòu)類型操作數(shù)的sizeof是這種類

7、型對(duì)象的總字節(jié)數(shù),包括任何墊補(bǔ)在內(nèi)。讓我們看如下結(jié)構(gòu):structcharb;doublex;a;在某些機(jī)器上sizeof(a)=12,而一般sizeof(char)+sizeof(double)=9。這是因?yàn)榫幾g器在考慮對(duì)齊問(wèn)題時(shí),在結(jié)構(gòu)中插入空位以控制各成員對(duì)象的地址對(duì)齊。如double類型的結(jié)構(gòu)成員x要放在被4整除的地址。6、如果操作數(shù)是函數(shù)中的數(shù)組形參或函數(shù)類型的形參,sizeof給出其指針的大小。四、sizeof與其他操作符的關(guān)系 sizeof的優(yōu)先級(jí)為2級(jí),比/、%等3級(jí)運(yùn)算符優(yōu)先級(jí)高。它可以與其他操作符一起組成表達(dá)式。如i*sizeof(int);其中i為int類型變量。五、si

8、zeof的主要用途 1、sizeof操作符的一個(gè)主要用途是與存儲(chǔ)分配和I/O系統(tǒng)那樣的例程進(jìn)行通信。例如:void*malloc(size_tsize),size_tfread(void*ptr,size_tsize,size_tnmemb,FILE*stream)。2、sizeof的另一個(gè)的主要用途是計(jì)算數(shù)組中元素的個(gè)數(shù)。例如:void*memset(void*s,intc,sizeof(s))。六、建議 由于操作數(shù)的字節(jié)數(shù)在實(shí)現(xiàn)時(shí)可能出現(xiàn)變化,建議在涉及到操作數(shù)字節(jié)大小時(shí)用sizeof來(lái)代替常量計(jì)算。=本文主要包括二個(gè)部分,第一部分重點(diǎn)介紹在VC中,怎么樣采用sizeof來(lái)求結(jié)構(gòu)的大小,以

9、及容易出現(xiàn)的問(wèn)題,并給出解決問(wèn)題的方法,第二部分總結(jié)出VC中sizeof的主要用法。1、 sizeof應(yīng)用在結(jié)構(gòu)上的情況請(qǐng)看下面的結(jié)構(gòu):struct MyStructdouble dda1;char dda;int type;對(duì)結(jié)構(gòu)MyStruct采用sizeof會(huì)出現(xiàn)什么結(jié)果呢?sizeof(MyStruct)為多少呢?也許你會(huì)這樣求:sizeof(MyStruct)=sizeof(double)+sizeof(char)+sizeof(int)=13但是當(dāng)在VC中測(cè)試上面結(jié)構(gòu)的大小時(shí),你會(huì)發(fā)現(xiàn)sizeof(MyStruct)為16。你知道為什么在VC中會(huì)得出這樣一個(gè)結(jié)果嗎?其實(shí),這是VC對(duì)

10、變量存儲(chǔ)的一個(gè)特殊處理。為了提高CPU的存儲(chǔ)速度,VC對(duì)一些變量的起始地址做了"對(duì)齊"處理。在默認(rèn)情況下,VC規(guī)定各成員變量存放的起始地址相對(duì)于結(jié)構(gòu)的起始地址的偏移量必須為該變量的類型所占用的字節(jié)數(shù)的倍數(shù)。下面列出常用類型的對(duì)齊方式(vc6.0,32位系統(tǒng))。類型 對(duì)齊方式(變量存放的起始地址相對(duì)于結(jié)構(gòu)的起始地址的偏移量)Char 偏移量必須為sizeof(char)即1的倍數(shù)int 偏移量必須為sizeof(int)即4的倍數(shù)float 偏移量必須為sizeof(float)即4的倍數(shù)double 偏移量必須為sizeof(double)即8的倍數(shù)Short 偏移量必須為

11、sizeof(short)即2的倍數(shù)各成員變量在存放的時(shí)候根據(jù)在結(jié)構(gòu)中出現(xiàn)的順序依次申請(qǐng)空間,同時(shí)按照上面的對(duì)齊方式調(diào)整位置,空缺的字節(jié)VC會(huì)自動(dòng)填充。同時(shí)VC為了確保結(jié)構(gòu)的大小為結(jié)構(gòu)的字節(jié)邊界數(shù)(即該結(jié)構(gòu)中占用最大空間的類型所占用的字節(jié)數(shù))的倍數(shù),所以在為最后一個(gè)成員變量申請(qǐng)空間后,還會(huì)根據(jù)需要自動(dòng)填充空缺的字節(jié)。下面用前面的例子來(lái)說(shuō)明VC到底怎么樣來(lái)存放結(jié)構(gòu)的。struct MyStructdouble dda1;char dda;int type;為上面的結(jié)構(gòu)分配空間的時(shí)候,VC根據(jù)成員變量出現(xiàn)的順序和對(duì)齊方式,先為第一個(gè)成員dda1分配空間,其起始地址跟結(jié)構(gòu)的起始地址相同(剛好偏移量0

12、剛好為sizeof(double)的倍數(shù)),該成員變量占用sizeof(double)=8個(gè)字節(jié);接下來(lái)為第二個(gè)成員dda分配空間,這時(shí)下一個(gè)可以分配的地址對(duì)于結(jié)構(gòu)的起始地址的偏移量為8,是sizeof(char)的倍數(shù),所以把dda存放在偏移量為8的地方滿足對(duì)齊方式,該成員變量占用sizeof(char)=1個(gè)字節(jié);接下來(lái)為第三個(gè)成員type分配空間,這時(shí)下一個(gè)可以分配的地址對(duì)于結(jié)構(gòu)的起始地址的偏移量為9,不是sizeof(int)=4的倍數(shù),為了滿足對(duì)齊方式對(duì)偏移量的約束問(wèn)題,VC自動(dòng)填充3個(gè)字節(jié)(這三個(gè)字節(jié)沒(méi)有放什么東西),這時(shí)下一個(gè)可以分配的地址對(duì)于結(jié)構(gòu)的起始地址的偏移量為12,剛好是

13、sizeof(int)=4的倍數(shù),所以把type存放在偏移量為12的地方,該成員變量占用sizeof(int)=4個(gè)字節(jié);這時(shí)整個(gè)結(jié)構(gòu)的成員變量已經(jīng)都分配了空間,總的占用的空間大小為:8+1+3+4=16,剛好為結(jié)構(gòu)的字節(jié)邊界數(shù)(即結(jié)構(gòu)中占用最大空間的類型所占用的字節(jié)數(shù)sizeof(double)=8)的倍數(shù),所以沒(méi)有空缺的字節(jié)需要填充。所以整個(gè)結(jié)構(gòu)的大小為:sizeof(MyStruct)=8+1+3+4=16,其中有3個(gè)字節(jié)是VC自動(dòng)填充的,沒(méi)有放任何有意義的東西。下面再舉個(gè)例子,交換一下上面的MyStruct的成員變量的位置,使它變成下面的情況:struct MyStructchar d

14、da;double dda1;  int type;這個(gè)結(jié)構(gòu)占用的空間為多大呢?在VC6.0環(huán)境下,可以得到sizeof(MyStruc)為24。結(jié)合上面提到的分配空間的一些原則,分析下VC怎么樣為上面的結(jié)構(gòu)分配空間的。(簡(jiǎn)單說(shuō)明)struct MyStructchar dda;/偏移量為0,滿足對(duì)齊方式,dda占用1個(gè)字節(jié);double dda1;/下一個(gè)可用的地址的偏移量為1,不是sizeof(double)=8             /的倍數(shù),需要

15、補(bǔ)足7個(gè)字節(jié)才能使偏移量變?yōu)?(滿足對(duì)齊             /方式),因此VC自動(dòng)填充7個(gè)字節(jié),dda1存放在偏移量為8             /的地址上,它占用8個(gè)字節(jié)。int type;/下一個(gè)可用的地址的偏移量為16,是sizeof(int)=4的倍        

16、   /數(shù),滿足int的對(duì)齊方式,所以不需要VC自動(dòng)填充,type存           /放在偏移量為16的地址上,它占用4個(gè)字節(jié)。;/所有成員變量都分配了空間,空間總的大小為1+7+8+4=20,不是結(jié)構(gòu)   /的節(jié)邊界數(shù)(即結(jié)構(gòu)中占用最大空間的類型所占用的字節(jié)數(shù)sizeof   /(double)=8)的倍數(shù),所以需要填充4個(gè)字節(jié),以滿足結(jié)構(gòu)的大小為   /sizeof(double)=8的倍數(shù)。所以該結(jié)構(gòu)總的

17、大小為:sizeof(MyStruc)為1+7+8+4+4=24。其中總的有7+4=11個(gè)字節(jié)是VC自動(dòng)填充的,沒(méi)有放任何有意義的東西。VC對(duì)結(jié)構(gòu)的存儲(chǔ)的特殊處理確實(shí)提高CPU存儲(chǔ)變量的速度,但是有時(shí)候也帶來(lái)了一些麻煩,我們也屏蔽掉變量默認(rèn)的對(duì)齊方式,自己可以設(shè)定變量的對(duì)齊方式。VC中提供了#pragma pack(n)來(lái)設(shè)定變量以n字節(jié)對(duì)齊方式。n字節(jié)對(duì)齊就是說(shuō)變量存放的起始地址的偏移量有兩種情況:第一、如果n大于等于該變量所占用的字節(jié)數(shù),那么偏移量必須滿足默認(rèn)的對(duì)齊方式,第二、如果n小于該變量的類型所占用的字節(jié)數(shù),那么偏移量為n的倍數(shù),不用滿足默認(rèn)的對(duì)齊方式。結(jié)構(gòu)的總大小也有個(gè)約束條件,分

18、下面兩種情況:如果n大于所有成員變量類型所占用的字節(jié)數(shù),那么結(jié)構(gòu)的總大小必須為占用空間最大的變量占用的空間數(shù)的倍數(shù);否則必須為n的倍數(shù)。下面舉例說(shuō)明其用法。#pragma pack(push) /保存對(duì)齊狀態(tài)#pragma pack(4)/設(shè)定為4字節(jié)對(duì)齊struct testchar m1;double m4;int m3;#pragma pack(pop)/恢復(fù)對(duì)齊狀態(tài)以上結(jié)構(gòu)的大小為16,下面分析其存儲(chǔ)情況,首先為m1分配空間,其偏移量為0,滿足我們自己設(shè)定的對(duì)齊方式(4字節(jié)對(duì)齊),m1占用1個(gè)字節(jié)。接著開(kāi)始為m4分配空間,這時(shí)其偏移量為1,需要補(bǔ)足3個(gè)字節(jié),這樣使偏移量滿足為n=4的倍

19、數(shù)(因?yàn)閟izeof(double)大于n),m4占用8個(gè)字節(jié)。接著為m3分配空間,這時(shí)其偏移量為12,滿足為4的倍數(shù),m3占用4個(gè)字節(jié)。這時(shí)已經(jīng)為所有成員變量分配了空間,共分配了16個(gè)字節(jié),滿足為n的倍數(shù)。如果把上面的#pragma pack(4)改為#pragma pack(16),那么我們可以得到結(jié)構(gòu)的大小為24。(請(qǐng)讀者自己分析)2、 sizeof用法總結(jié)在VC中,sizeof有著許多的用法,而且很容易引起一些錯(cuò)誤。下面根據(jù)sizeof后面的參數(shù)對(duì)sizeof的用法做個(gè)總結(jié)。A 參數(shù)為數(shù)據(jù)類型或者為一般變量。例如sizeof(int),sizeof(long)等等。這種情況要注意的是不

20、同系統(tǒng)系統(tǒng)或者不同編譯器得到的結(jié)果可能是不同的。例如int類型在16位系統(tǒng)中占2個(gè)字節(jié),在32位系統(tǒng)中占4個(gè)字節(jié)。B 參數(shù)為數(shù)組或指針。下面舉例說(shuō)明.int a50; /sizeof(a)=4*50=200; 求數(shù)組所占的空間大小int *a=new int50;/ sizeof(a)=4; a為一個(gè)指針,sizeof(a)是求指針                   /的大小,在32位系統(tǒng)中,當(dāng)然是占4個(gè)字節(jié)。C

21、參數(shù)為結(jié)構(gòu)或類。Sizeof應(yīng)用在類和結(jié)構(gòu)的處理情況是相同的。但有兩點(diǎn)需要注意,第一、結(jié)構(gòu)或者類中的靜態(tài)成員不對(duì)結(jié)構(gòu)或者類的大小產(chǎn)生影響,因?yàn)殪o態(tài)變量的存儲(chǔ)位置與結(jié)構(gòu)或者類的實(shí)例地址無(wú)關(guān)。第二、沒(méi)有成員變量的結(jié)構(gòu)或類的大小為1,因?yàn)楸仨毐WC結(jié)構(gòu)或類的每一個(gè)實(shí)例在內(nèi)存中都有唯一的地址。下面舉例說(shuō)明,Class Testint a;static double c;/sizeof(Test)=4.Test *s;/sizeof(s)=4,s為一個(gè)指針。Class test1 ;/sizeof(test1)=1;D 參數(shù)為其他。下面舉例說(shuō)明。   int func(char s5)

22、;        cout<<sizeof(s);/這里將輸出4,本來(lái)s為一個(gè)數(shù)組,但由于做為函                     /數(shù)的參數(shù)在傳遞的時(shí)候系統(tǒng)處理為一個(gè)指針,所            &

23、#160;        /以sizeof(s)實(shí)際上為求指針的大小。     return 1;sizeof(func("1234")=4/因?yàn)閒unc的返回類型為int,所以相當(dāng)于                     /求sizeof(int).以上為sizeo

24、f的基本用法,在實(shí)際的使用中要注意分析VC的分配變量的分配策略,這樣的話可以避免一些錯(cuò)誤。在對(duì)齊為4的情況下struct BBB      long num;      char *name;      short int data;      char ha;      short ba5;*p;p=0x1000000;p+0x200=_;(Ul

25、ong)p+0x200=_;(char*)p+0x200=_;希望各位達(dá)人給出答案和原因,謝謝拉解答:假設(shè)在32位CPU上,sizeof(long) = 4 bytessizeof(char *) = 4 bytessizeof(short int) = sizeof(short) = 2 bytessizeof(char) = 1 bytes由于是4字節(jié)對(duì)齊,sizeof(struct BBB) = sizeof(*p) = 4 + 4 + 2 + 1 + 1/*補(bǔ)齊*/ + 2*5 + 2/*補(bǔ)齊*/ = 24 bytes     (經(jīng)Dev-C+驗(yàn)

26、證)p=0x1000000;p+0x200=_;       = 0x1000000 + 0x200*24(Ulong)p+0x200=_;       = 0x1000000 + 0x200(char*)p+0x200=_;       = 0x1000000 + 0x200*4你可以參考一下指針運(yùn)算的細(xì)節(jié)2.找錯(cuò)題試題1:void test1()char string10;char* str1 = "0

27、123456789"strcpy( string, str1 );試題2:void test2()char string10, str110;int i;for(i=0; i<10; i+)str1 = 'a'strcpy( string, str1 );試題3:void test3(char* str1)char string10;if( strlen( str1 ) <= 10 )strcpy( string, str1 );解答:試題1字符串str1需要11個(gè)字節(jié)才能存放下(包括末尾的0),而string只有10個(gè)字節(jié)的空間,strcpy會(huì)導(dǎo)致數(shù)組越

28、界;對(duì)試題2,如果面試者指出字符數(shù)組str1不能在數(shù)組內(nèi)結(jié)束可以給3分;如果面試者指出strcpy(string, str1)調(diào)用使得從str1內(nèi)存起復(fù)制到string內(nèi)存起所復(fù)制的字節(jié)數(shù)具有不確定性可以給7分,在此基礎(chǔ)上指出庫(kù)函數(shù)strcpy工作方式的給10分;對(duì)試題3,if(strlen(str1) <= 10)應(yīng)改為if(strlen(str1) < 10),因?yàn)閟trlen的結(jié)果未統(tǒng)計(jì)0所占用的1個(gè)字節(jié)。剖析:考查對(duì)基本功的掌握:(1)字符串以0結(jié)尾;(2)對(duì)數(shù)組越界把握的敏感度;(3)庫(kù)函數(shù)strcpy的工作方式,如果編寫一個(gè)標(biāo)準(zhǔn)strcpy函數(shù)的總分值為10,下面給出幾

29、個(gè)不同得分的答案:2分void strcpy( char *strDest, char *strSrc ) while( (*strDest+ = * strSrc+) != 0 );4分void strcpy( char *strDest, const char *strSrc ) /將源字符串加const,表明其為輸入?yún)?shù),加2分 while( (*strDest+ = * strSrc+) != 0 );7分void strcpy(char *strDest, const char *strSrc) /對(duì)源地址和目的地址加非0斷言,加3分assert( (strDest != NULL)

30、 && (strSrc != NULL) );while( (*strDest+ = * strSrc+) != 0 );10分/為了實(shí)現(xiàn)鏈?zhǔn)讲僮?,將目的地址返回,?分!char * strcpy( char *strDest, const char *strSrc ) assert( (strDest != NULL) && (strSrc != NULL) );char *address = strDest; while( (*strDest+ = * strSrc+) != 0 ); return address;從2分到10分的幾個(gè)答案我們可以清楚的看

31、到,小小的strcpy竟然暗藏著這么多玄機(jī),真不是蓋的!需要多么扎實(shí)的基本功才能寫一個(gè)完美的strcpy?。?4)對(duì)strlen的掌握,它沒(méi)有包括字符串末尾的'0'。讀者看了不同分值的strcpy版本,應(yīng)該也可以寫出一個(gè)10分的strlen函數(shù)了,完美的版本為: int strlen( const char *str ) /輸入?yún)?shù)constassert( strt != NULL ); /斷言字符串地址非0int len;while( (*str+) != '0' ) len+; return len;-34.請(qǐng)指出下列程序中的錯(cuò)誤并且修改void GetMe

32、mory(char *p)p=(char *)malloc(100);void Test(void)char *str=NULL;GetMemory=(str);strcpy(str,"hello world");printf(str);A:錯(cuò)誤-參數(shù)的值改變后,不會(huì)傳回GetMemory并不能傳遞動(dòng)態(tài)內(nèi)存,Test函數(shù)中的 str一直都是 NULL。strcpy(str, "hello world");將使程序崩潰。修改如下:char *GetMemory()char *p=(char *)malloc(100);return p;void Test(

33、void)char *str=NULL;str=GetMemory()strcpy(str,"hello world");printf(str);方法二:void GetMemory2(char *p)變?yōu)槎?jí)指針.void GetMemory2(char *p, int num)*p = (char *)malloc(sizeof(char) * num);試題4:void GetMemory( char *p )p = (char *) malloc( 100 );void Test( void ) char *str = NULL;GetMemory( str );

34、strcpy( str, "hello world" );printf( str );試題5:char *GetMemory( void ) char p = "hello world" return p; void Test( void ) char *str = NULL; str = GetMemory(); printf( str ); 試題6:void GetMemory( char *p, int num )*p = (char *) malloc( num );void Test( void )char *str = NULL;GetMem

35、ory( &str, 100 );strcpy( str, "hello" ); printf( str ); 試題7:void Test( void )char *str = (char *) malloc( 100 );strcpy( str, "hello" );free( str ); . /省略的其它語(yǔ)句解答:試題4傳入中GetMemory( char *p )函數(shù)的形參為字符串指針,在函數(shù)內(nèi)部修改形參并不能真正的改變傳入形參的值,執(zhí)行完char *str = NULL;GetMemory( str ); 后的str仍然為NULL;試題

36、中char p = "hello world" return p; 的p數(shù)組為函數(shù)內(nèi)的局部自動(dòng)變量,在函數(shù)返回后,內(nèi)存已經(jīng)被釋放。這是許多程序員常犯的錯(cuò)誤,其根源在于不理解變量的生存期。試題6的GetMemory避免了試題4的問(wèn)題,傳入GetMemory的參數(shù)為字符串指針的指針,但是在GetMemory中執(zhí)行申請(qǐng)內(nèi)存及賦值語(yǔ)句*p = (char *) malloc( num );后未判斷內(nèi)存是否申請(qǐng)成功,應(yīng)加上:if ( *p = NULL )./進(jìn)行申請(qǐng)內(nèi)存失敗處理試題7存在與試題6同樣的問(wèn)題,在執(zhí)行char *str = (char *) malloc(100);后未

37、進(jìn)行內(nèi)存是否申請(qǐng)成功的判斷;另外,在free(str)后未置str為空,導(dǎo)致可能變成一個(gè)“野”指針,應(yīng)加上:str = NULL;試題6的Test函數(shù)中也未對(duì)malloc的內(nèi)存進(jìn)行釋放。剖析:試題47考查面試者對(duì)內(nèi)存操作的理解程度,基本功扎實(shí)的面試者一般都能正確的回答其中5060的錯(cuò)誤。但是要完全解答正確,卻也絕非易事。對(duì)內(nèi)存操作的考查主要集中在:(1)指針的理解;(2)變量的生存期及作用范圍;(3)良好的動(dòng)態(tài)內(nèi)存申請(qǐng)和釋放習(xí)慣。再看看下面的一段程序有什么錯(cuò)誤:swap( int* p1,int* p2 )int *p;*p = *p1;*p1 = *p2;*p2 = *p;在swap函數(shù)中,

38、p是一個(gè)“野”指針,有可能指向系統(tǒng)區(qū),導(dǎo)致程序運(yùn)行的崩潰。在VC+中DEBUG運(yùn)行時(shí)提示錯(cuò)誤“Access Violation”。該程序應(yīng)該改為:swap( int* p1,int* p2 )int p;p = *p1;*p1 = *p2;*p2 = p;內(nèi)功題試題1:分別給出BOOL,int,float,指針變量 與“零值”比較的 if 語(yǔ)句(假設(shè)變量名為var)解答:BOOL型變量:if(!var)int型變量: if(var=0)float型變量:const float EPSINON = 0.00001;if (x >= - EPSINON) && (x <

39、= EPSINON)指針變量:if(var=NULL)剖析:考查對(duì)0值判斷的“內(nèi)功”,BOOL型變量的0判斷完全可以寫成if(var=0),而int型變量也可以寫成if(!var),指針變量的判斷也可以寫成if(!var),上述寫法雖然程序都能正確運(yùn)行,但是未能清晰地表達(dá)程序的意思。 一般的,如果想讓if判斷一個(gè)變量的“真”、“假”,應(yīng)直接使用if(var)、if(!var),表明其為“邏輯”判斷;如果用if判斷一個(gè)數(shù)值型變量(short、int、long等),應(yīng)該用if(var=0),表明是與0進(jìn)行“數(shù)值”上的比較;而判斷指針則適宜用if(var=NULL),這是一種很好的編程習(xí)慣。浮點(diǎn)型變

40、量并不精確,所以不可將float變量用“=”或“!=”與數(shù)字比較,應(yīng)該設(shè)法轉(zhuǎn)化成“>=”或“<=”形式。如果寫成if (x = 0.0),則判為錯(cuò),得0分。試題2:以下為Windows NT下的32位C+程序,請(qǐng)計(jì)算sizeof的值void Func ( char str100 )sizeof( str ) = ?void *p = malloc( 100 );sizeof ( p ) = ?解答:sizeof( str ) = 4sizeof ( p ) = 4剖析:Func ( char str100 )函數(shù)中數(shù)組名作為函數(shù)形參時(shí),在函數(shù)體內(nèi),數(shù)組名失去了本身的內(nèi)涵,僅僅只是一

41、個(gè)指針;在失去其內(nèi)涵的同時(shí),它還失去了其常量特性,可以作自增、自減等操作,可以被修改。數(shù)組名的本質(zhì)如下:(1)數(shù)組名指代一種數(shù)據(jù)結(jié)構(gòu),這種數(shù)據(jù)結(jié)構(gòu)就是數(shù)組;例如:char str10;cout sizeof(str) endl;輸出結(jié)果為10,str指代數(shù)據(jù)結(jié)構(gòu)char10。(2)數(shù)組名可以轉(zhuǎn)換為指向其指代實(shí)體的指針,而且是一個(gè)指針常量,不能作自增、自減等操作,不能被修改;char str10; str+; /編譯出錯(cuò),提示str不是左值(3)數(shù)組名作為函數(shù)形參時(shí),淪為普通指針。Windows NT 32位平臺(tái)下,指針的長(zhǎng)度(占用內(nèi)存的大?。?字節(jié),故sizeof( str ) 、sizeo

42、f ( p ) 都為4。試題3:寫一個(gè)“標(biāo)準(zhǔn)”宏MIN,這個(gè)宏輸入兩個(gè)參數(shù)并返回較小的一個(gè)。另外,當(dāng)你寫下面的代碼時(shí)會(huì)發(fā)生什么事?least = MIN(*p+, b);解答:#define MIN(A,B) (A) <= (B) ? (A) : (B)MIN(*p+, b)會(huì)產(chǎn)生宏的副作用剖析:這個(gè)面試題主要考查面試者對(duì)宏定義的使用,宏定義可以實(shí)現(xiàn)類似于函數(shù)的功能,但是它終歸不是函數(shù),而宏定義中括弧中的“參數(shù)”也不是真的參數(shù),在宏展開(kāi)的時(shí)候?qū)Α皡?shù)”進(jìn)行的是一對(duì)一的替換。程序員對(duì)宏定義的使用要非常小心,特別要注意兩個(gè)問(wèn)題:(1)謹(jǐn)慎地將宏定義中的“參數(shù)”和整個(gè)宏用用括弧括起來(lái)。所以,嚴(yán)

43、格地講,下述解答:#define MIN(A,B) (A) <= (B) ? (A) : (B)#define MIN(A,B) (A <= B ? A : B )都應(yīng)判0分;(2)防止宏的副作用。宏定義#define MIN(A,B) (A) <= (B) ? (A) : (B)對(duì)MIN(*p+, b)的作用結(jié)果是:(*p+) <= (b) ? (*p+) : (*p+)這個(gè)表達(dá)式會(huì)產(chǎn)生副作用,指針p會(huì)作三次+自增操作。除此之外,另一個(gè)應(yīng)該判0分的解答是:#define MIN(A,B) (A) <= (B) ? (A) : (B); 這個(gè)解答在宏定義的后面加“

44、;”,顯示編寫者對(duì)宏的概念模糊不清,只能被無(wú)情地判0分并被面試官淘汰。C+拾遺(12)含參數(shù)的宏與函數(shù)的區(qū)別  0推薦1.函數(shù)調(diào)用時(shí),先求出實(shí)參表達(dá)式的值,然后帶入形參。而使用帶參的宏只是進(jìn)行簡(jiǎn)單的字符替換。2.函數(shù)調(diào)用是在程序運(yùn)行時(shí)處理的,分配臨時(shí)的內(nèi)存單元;而宏展開(kāi)則是在編譯時(shí)進(jìn)行的,在展開(kāi)時(shí)并不分配內(nèi)存單元,不進(jìn)行值的傳遞處理,也沒(méi)有“返回值”的概念。3.對(duì)函數(shù)中的實(shí)參和形參都要定義類型,二者的類型要求一致,如不一致,應(yīng)進(jìn)行類型轉(zhuǎn)換;而宏不存在類型問(wèn)題,宏名無(wú)類型,它的參數(shù)也無(wú)類型,只是一個(gè)符號(hào)代表,展開(kāi)時(shí)帶入指定的字符即可。宏定義時(shí),字符串可以是任何類型的數(shù)據(jù)。4.

45、調(diào)用函數(shù)只可得到一個(gè)返回值,而用宏可以設(shè)法得到幾個(gè)結(jié)果。5.使用宏次數(shù)多時(shí),宏展開(kāi)后源程序長(zhǎng),因?yàn)槊空归_(kāi)一次都使程序增長(zhǎng),而函數(shù)調(diào)用不使源程序變長(zhǎng)。6.宏替換不占運(yùn)行時(shí)間,只占編譯時(shí)間;而函數(shù)調(diào)用則占運(yùn)行時(shí)間(分配單元、保留現(xiàn)場(chǎng)、值傳遞、返回)。一般來(lái)說(shuō),用宏來(lái)代表簡(jiǎn)短的表達(dá)式比較合適。有時(shí)使用宏時(shí)會(huì)引起理解錯(cuò)誤:例:i nclude<iostream.h>#define max(a,b) (a>b)?a:b)void main() int i=3,j=2; cout<<max(+i,j)<<endl; cout<&

46、lt;i<<"  "<<j<<endl;運(yùn)行結(jié)果:55  2頭文件中的編譯宏#ifndef_INCvxWorksh#define_INCvxWorksh#endif 的作用是防止被重復(fù)引用。作為一種面向?qū)ο蟮恼Z(yǔ)言,C+支持函數(shù)重載,而過(guò)程式語(yǔ)言C則不支持。函數(shù)被C+編譯后在symbol庫(kù)中的名字與C語(yǔ)言的不同。例如,假設(shè)某個(gè)函數(shù)的原型為: void foo(int x, int y);該函數(shù)被C編譯器編譯后在symbol庫(kù)中的名字為_(kāi)foo,而C+編譯器則會(huì)產(chǎn)生像_foo_int_int之類的名字。_foo_int_i

47、nt這樣的名字包含了函數(shù)名和函數(shù)參數(shù)數(shù)量及類型信息,C+就是考這種機(jī)制來(lái)實(shí)現(xiàn)函數(shù)重載的。為了實(shí)現(xiàn)C和C+的混合編程,C+提供了C連接交換指定符號(hào)extern "C"來(lái)解決名字匹配問(wèn)題,函數(shù)聲明前加上extern "C"后,則編譯器就會(huì)按照C語(yǔ)言的方式將該函數(shù)編譯為_(kāi)foo,這樣C語(yǔ)言中就可以調(diào)用C+的函數(shù)了。試題8:請(qǐng)說(shuō)出static和const關(guān)鍵字盡可能多的作用解答:static關(guān)鍵字至少有下列n個(gè)作用:(1)函數(shù)體內(nèi)static變量的作用范圍為該函數(shù)體,不同于auto變量,該變量的內(nèi)存只被分配一次,因此其值在下次調(diào)用時(shí)仍維持上次的值;(2)在模塊內(nèi)

48、的static全局變量可以被模塊內(nèi)所用函數(shù)訪問(wèn),但不能被模塊外其它函數(shù)訪問(wèn);(3)在模塊內(nèi)的static函數(shù)只可被這一模塊內(nèi)的其它函數(shù)調(diào)用,這個(gè)函數(shù)的使用范圍被限制在聲明它的模塊內(nèi);(4)在類中的static成員變量屬于整個(gè)類所擁有,對(duì)類的所有對(duì)象只有一份拷貝;(5)在類中的static成員函數(shù)屬于整個(gè)類所擁有,這個(gè)函數(shù)不接收this指針,因而只能訪問(wèn)類的static成員變量。 const關(guān)鍵字至少有下列n個(gè)作用:(1)欲阻止一個(gè)變量被改變,可以使用const關(guān)鍵字。在定義該const變量時(shí),通常需要對(duì)它進(jìn)行初始化,因?yàn)橐院缶蜎](méi)有機(jī)會(huì)再去改變它了;(2)對(duì)指針來(lái)說(shuō),可以指定指針本身為const

49、,也可以指定指針?biāo)傅臄?shù)據(jù)為const,或二者同時(shí)指定為const;(3)在一個(gè)函數(shù)聲明中,const可以修飾形參,表明它是一個(gè)輸入?yún)?shù),在函數(shù)內(nèi)部不能改變其值;(4)對(duì)于類的成員函數(shù),若指定其為const類型,則表明其是一個(gè)常函數(shù),不能修改類的成員變量;(5)對(duì)于類的成員函數(shù),有時(shí)候必須指定其返回值為const類型,以使得其返回值不為“左值”。例如:const classA operator*(const classA& a1,const classA& a2);operator*的返回結(jié)果必須是一個(gè)const對(duì)象。如果不是,這樣的變態(tài)代碼也不會(huì)編譯出錯(cuò):classA a,

50、b, c;(a * b) = c; / 對(duì)a*b的結(jié)果賦值操作(a * b) = c顯然不符合編程者的初衷,也沒(méi)有任何意義。函數(shù)和宏函數(shù)的區(qū)別就在于,宏函數(shù)占用了大量的空間,而函數(shù)占用了時(shí)間。大家要知道的是,函數(shù)調(diào)用是要使用系統(tǒng)的棧來(lái)保存數(shù)據(jù)的,如果編譯器里有棧檢查選項(xiàng),一般在函數(shù)的頭會(huì)嵌入一些匯編語(yǔ)句對(duì)當(dāng)前棧進(jìn)行檢查;同時(shí),CPU也要在函數(shù)調(diào)用時(shí)保存和恢復(fù)當(dāng)前的現(xiàn)場(chǎng),進(jìn)行壓棧和彈棧操作,所以,函數(shù)調(diào)用需要一些CPU時(shí)間。而宏函數(shù)不存在這個(gè)問(wèn)題。宏函數(shù)僅僅作為預(yù)先寫好的代碼嵌入到當(dāng)前程序,不會(huì)產(chǎn)生函數(shù)調(diào)用,所以僅僅是占用了空間,在頻繁調(diào)用同一個(gè)宏函數(shù)的時(shí)候,該現(xiàn)象尤其突出。 D方法是我看到的最

51、好的置位操作函數(shù),是ARM公司源碼的一部分,在短短的三行內(nèi)實(shí)現(xiàn)了很多功能,幾乎涵蓋了所有的位操作功能。C方法是其變體,其中滋味還需大家仔細(xì)體會(huì)。編程新手常犯這種錯(cuò)誤,因?yàn)樗麄儧](méi)有意識(shí)到內(nèi)存分配會(huì)不成功。常用解決辦法是,在使用內(nèi)存之前檢查指針是否為NULL。如果指針p是函數(shù)的參數(shù),那么在函數(shù)的入口處用assert(p!=NULL)進(jìn)行檢查。如果是用malloc或new來(lái)申請(qǐng)內(nèi)存,應(yīng)該用if(p=NULL) 或if(p!=NULL)進(jìn)行防錯(cuò)處理。* 內(nèi)存分配雖然成功,但是尚未初始化就引用它。犯這種錯(cuò)誤主要有兩個(gè)起因:一是沒(méi)有初始化的觀念;二是誤以為內(nèi)存的缺省初值全為零,導(dǎo)致引用初值錯(cuò)誤(例如數(shù)組)

52、。 內(nèi)存的缺省初值究竟是什么并沒(méi)有統(tǒng)一的標(biāo)準(zhǔn),盡管有些時(shí)候?yàn)榱阒?,我們寧可信其無(wú)不可信其有。所以無(wú)論用何種方式創(chuàng)建數(shù)組,都別忘了賦初值,即便是賦零值也不可省略,不要嫌麻煩。* 內(nèi)存分配成功并且已經(jīng)初始化,但操作越過(guò)了內(nèi)存的邊界。例如在使用數(shù)組時(shí)經(jīng)常發(fā)生下標(biāo)“多1”或者“少1”的操作。特別是在for循環(huán)語(yǔ)句中,循環(huán)次數(shù)很容易搞錯(cuò),導(dǎo)致數(shù)組操作越界。* 忘記了釋放內(nèi)存,造成內(nèi)存泄露。含有這種錯(cuò)誤的函數(shù)每被調(diào)用一次就丟失一塊內(nèi)存。剛開(kāi)始時(shí)系統(tǒng)的內(nèi)存充足,你看不到錯(cuò)誤。終有一次程序突然死掉,系統(tǒng)出現(xiàn)提示:內(nèi)存耗盡。動(dòng)態(tài)內(nèi)存的申請(qǐng)與釋放必須配對(duì),程序中malloc與free的使用次數(shù)一定要相同,否則肯定

53、有錯(cuò)誤(new/delete同理)。* 釋放了內(nèi)存卻繼續(xù)使用它。有三種情況:(1)程序中的對(duì)象調(diào)用關(guān)系過(guò)于復(fù)雜,實(shí)在難以搞清楚某個(gè)對(duì)象究竟是否已經(jīng)釋放了內(nèi)存,此時(shí)應(yīng)該重新設(shè)計(jì)數(shù)據(jù)結(jié)構(gòu),從根本上解決對(duì)象管理的混亂局面。(2)函數(shù)的return語(yǔ)句寫錯(cuò)了,注意不要返回指向“棧內(nèi)存”的“指針”或者“引用”,因?yàn)樵搩?nèi)存在函數(shù)體結(jié)束時(shí)被自動(dòng)銷毀。(3)使用free或delete釋放了內(nèi)存后,沒(méi)有將指針設(shè)置為NULL。導(dǎo)致產(chǎn)生“野指針”。  【規(guī)則1】用malloc或new申請(qǐng)內(nèi)存之后,應(yīng)該立即檢查指針值是否為NULL。防止使用指針值為NULL的內(nèi)存?!疽?guī)則2】不要忘記為數(shù)組和動(dòng)態(tài)內(nèi)存賦初值。防

54、止將未被初始化的內(nèi)存作為右值使用?!疽?guī)則3】避免數(shù)組或指針的下標(biāo)越界,特別要當(dāng)心發(fā)生“多1”或者“少1”操作?!疽?guī)則4】動(dòng)態(tài)內(nèi)存的申請(qǐng)與釋放必須配對(duì),防止內(nèi)存泄漏。【規(guī)則5】用free或delete釋放了內(nèi)存之后,立即將指針設(shè)置為NULL,防止產(chǎn)生“野指針”。我總結(jié)了在用C/C+語(yǔ)言(主要是C語(yǔ)言)進(jìn)行程序?qū)懽魃系娜€(gè)“修養(yǎng)”,通過(guò)這些,你可以寫出質(zhì)量高的程序,同時(shí)也會(huì)讓看你程序的人漬漬稱道,那些看過(guò)你程序的人一定會(huì)說(shuō):“這個(gè)人的編程修養(yǎng)不錯(cuò)”。 01、版權(quán)和版本 02、縮進(jìn)、空格、換行、空行、對(duì)齊 03、程序注釋 04、函數(shù)的inout參數(shù) 05、對(duì)系統(tǒng)調(diào)用的返回進(jìn)行判斷 06、if 語(yǔ)

55、句對(duì)出錯(cuò)的處理 07、頭文件中的#ifndef 08、在堆上分配內(nèi)存 09、變量的初始化 10、h和c文件的使用 11、出錯(cuò)信息的處理 12、常用函數(shù)和循環(huán)語(yǔ)句中的被計(jì)算量 13、函數(shù)名和變量名的命名 14、函數(shù)的傳值和傳指針 15、修改別人程序的修養(yǎng) 16、把相同或近乎相同的代碼形成函數(shù)和宏 17、表達(dá)式中的括號(hào) 18、函數(shù)參數(shù)中的const 19、函數(shù)的參數(shù)個(gè)數(shù) 20、函數(shù)的返回類型,不要省略 21、goto語(yǔ)句的使用 22、宏的使用 23、static的使用 24、函數(shù)中的代碼尺寸 25、typedef的使用 26、為常量聲明宏 27、不要為宏定義加分號(hào) 28、和&&的語(yǔ)

56、句執(zhí)行順序 29、盡量用for而不是while做循環(huán) 30、請(qǐng)sizeof類型而不是變量 31、不要忽略Warning 32、書寫Debug版和Release版的程序1 內(nèi)聯(lián)函數(shù)必須在調(diào)用前定義,2 內(nèi)聯(lián)函數(shù)中不能有復(fù)雜 的控制語(yǔ)句3 遞歸不能內(nèi)聯(lián),5只適用于1-5 行和小函數(shù)32.簡(jiǎn)述Critical Section和Mutex的不同點(diǎn)答:對(duì)幾種同步對(duì)象的總結(jié)1.Critical SectionA.速度快B.不能用于不同進(jìn)程C.不能進(jìn)行資源統(tǒng)計(jì)(每次只可以有一個(gè)線程對(duì)共享資源進(jìn)行存取)2.MutexA.速度慢B.可用于不同進(jìn)程C.不能進(jìn)行資源

57、統(tǒng)計(jì)3.SemaphoreA.速度慢B.可用于不同進(jìn)程C.可進(jìn)行資源統(tǒng)計(jì)(可以讓一個(gè)或超過(guò)一個(gè)線程對(duì)共享資源進(jìn)行存取)4.EventA.速度慢B.可用于不同進(jìn)程C.可進(jìn)行資源統(tǒng)計(jì)摩托羅拉C+面試題最近經(jīng)常在上CSDN看看,關(guān)注里面各位程序員的BLOG,主要是C+方面的,畢竟可以了解一些有用的東西。找到的一二摩托羅拉的C+面試題,學(xué)習(xí)下。1.介紹一下STL,詳細(xì)說(shuō)明STL如何實(shí)現(xiàn)vector。Answer:STL (標(biāo)準(zhǔn)模版庫(kù),Standard Template Library.它由容器算法迭代器組成。STL有以下的一些優(yōu)點(diǎn):可以方便容易地實(shí)現(xiàn)搜索數(shù)據(jù)或?qū)?shù)據(jù)排序等一系列的算法;調(diào)試程序時(shí)更加安全和方便;即使是人們用STL在UNIX平臺(tái)下寫的代碼你也可以很容易地理解(因?yàn)镾TL是跨平臺(tái)的)。vector實(shí)質(zhì)上就是一個(gè)動(dòng)態(tài)數(shù)組,會(huì)根據(jù)數(shù)據(jù)的增加,動(dòng)

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論