经典C++面试题
1.關(guān)于++a與a++
?
???int?a?=?5;?那么++(a++)的值是多少?
?????????
???說(shuō)到這道題,我們先來(lái)研究++a與a++的區(qū)別,編譯器對(duì)++a的調(diào)用,相當(dāng)于int?operator++?(int),可以看
? ?出,返回的依然是int類(lèi)型,所以無(wú)論在a的左邊無(wú)論有多少個(gè)++都是可以的。而對(duì)于a++則不同,在編譯器中,
? ?相當(dāng)于調(diào)用const?int?operator++?(),這里的const是一個(gè)常量,所以只能作為右值,不能再進(jìn)行++,所
???以a++++就不合法了。另外++a執(zhí)行后的結(jié)果還是保存在a中,即相當(dāng)于a?=?++a,而對(duì)于a++,執(zhí)行后的結(jié)果是
? ?保存在一個(gè)臨時(shí)變量中,這個(gè)臨時(shí)變量是一個(gè)const右值,用后很快就會(huì)消失的。所以,上面的++(a++)編譯會(huì)
? ?出錯(cuò)。
?
???那么,經(jīng)過(guò)上面的分析,我們來(lái)看下面這個(gè)題就容易多了。
???int?a?=?3;
???int?b?=?(++a)?+?(++a);
???int?c?=?(a++)?+?(a++);
???求b和c的值。
?
???對(duì)于b來(lái)說(shuō),我們先看++a,它相當(dāng)于a?=?++a,執(zhí)行完畢后,還有一個(gè)++a,所以得到a?=?5,最終就
? ?是b?=?a?+?a?=?10
?
???對(duì)于c來(lái)說(shuō),由于a++是先使用再++,即c?=?a?+?a?=?6,而a++的結(jié)果是一個(gè)臨時(shí)變量,后來(lái)就很快消失了,
? ?根本沒(méi)有用到。
?
2.指針
?
???求下面的代碼輸出結(jié)果
???int?a[5]?=?{1,2,3,4,5};
???int?*p?=?(int?*)(&a?+?1);
???printf("%d?%d\n",*(a+1),*(p-1));
?
???注意看清楚,這里是(&a?+?1),而不是(a?+?1),&a是指向數(shù)組的指針,是一個(gè)行指針,那么實(shí)際
? ?上(&a?+?1)越界了,我們的p-1恰好是數(shù)組的最后一個(gè)元素,所以應(yīng)該輸出2?5。實(shí)際上一維數(shù)組可以看成是特
? ?殊的二維數(shù)組,即a[1][5],那么上面的代碼與如下代碼是等價(jià)的:
???int?a[1][5]?=?{1,2,3,4,5};
???int?*p?=?(int?*)(&a?+?1);
???printf("%d?%d\n",*(a[0]+1),*(p-1));
?
3.char?s[]與char?*s
?
????char?s1[]?=?"abc";
????char?s2[]?=?"abc";
????char?*s3?=?"abc";
????char?*s4?=?"abc";
????cout<<(s1?==?s2)<<endl;
? ? cout<<(s3?==?s4)<<endl;
上面的代碼會(huì)輸出什么結(jié)果?
?
這就要來(lái)弄清楚char?s[]與char?*s的區(qū)別。對(duì)于char?s[]來(lái)說(shuō),它是每次都會(huì)開(kāi)辟一段內(nèi)存空間來(lái)存儲(chǔ)后面的
字符串內(nèi)容,有自己的存儲(chǔ)空間,無(wú)論字符串內(nèi)容是否一樣。而對(duì)于char??*s來(lái)說(shuō),是字符指針,不分配存儲(chǔ)空
間,而后面的字符串內(nèi)容存儲(chǔ)于靜態(tài)存儲(chǔ)區(qū),那么對(duì)應(yīng)的所有s指針都指向這個(gè)常量字符串,所以應(yīng)該輸出0?1。
?
4.關(guān)于sizeof
????
sizeof不是函數(shù),盡管它是這樣sizeof(str),或許你不知道,它其實(shí)還可以這樣sizeof?str,所以sizeof在C++中其實(shí)是一個(gè)關(guān)鍵字。
?
?char?s1[]?=?"abcdefg";
?????char?*s2?=?"abcdefg";
?char?s3[105]?=?"abcdefg";
?cout<<sizeof(s1)<<endl;
?cout<<sizeof(s2)<<endl;
?cout<<sizeof(s3)<<endl;
?
輸出結(jié)果依次為8?4?105
首先對(duì)于s1它是數(shù)組名字,對(duì)于s1[]?,它在內(nèi)存中開(kāi)辟了空間,所以sizeof?s1代表整個(gè)數(shù)組的長(zhǎng)度,注意數(shù)組
末尾還有一個(gè)’\0’,所以長(zhǎng)度為8。而對(duì)于s2,它是一個(gè)指針,我們知道指針存儲(chǔ)的是地址,在C++中一個(gè)地址是
用4字節(jié)來(lái)存儲(chǔ)的,所以s2永遠(yuǎn)是4。對(duì)于s3[105]來(lái)說(shuō),因?yàn)楸旧黹_(kāi)辟了105字節(jié)的空間,所以輸出105。
?
5.字符串拷貝函數(shù)
?????
寫(xiě)一個(gè)函數(shù),實(shí)現(xiàn)字符串拷貝功能,返回函數(shù)的指針,函數(shù)原型如下:
char?*strcpy(char?*strDest,?const?char?*strSrc);
為什么還要返回一個(gè)address,目的是實(shí)現(xiàn)鏈?zhǔn)奖磉_(dá)式。
? ??
上面的拷貝中似乎已經(jīng)達(dá)到很完美了,但是它只適用內(nèi)存空間不重疊的情況。如果內(nèi)存空間有重疊呢,就必須分情況進(jìn)行正向拷貝或者逆向拷貝。
void *memcpy(void *strDest,const void *strSrc,size_t cnt){ assert(strDest != NULL && strSrc != NULL);assert(cnt > 0);char *psrc = (char *)strSrc;char *pdest = (char *)strDest;if(pdest < psrc){while(cnt--)*pdest++ = *psrc++;}else if(psrc < pdest){psrc += cnt - 1;pdest += cnt - 1;while(cnt--)*pdest-- = *psrc--;}return strDest;}
6.常見(jiàn)指針
?
????int?*p[n];?????-----指針數(shù)組,每個(gè)元素均為指向整型數(shù)據(jù)的指針。
????int?(*)p[n];???-----p為指向一維數(shù)組的指針,這個(gè)一維數(shù)組有n個(gè)整型數(shù)據(jù)。
????int?*p();??????------函數(shù)返回指針,指針指向返回的值。
? ? int?(*)p();????------p為指向函數(shù)的指針。
總結(jié)
- 上一篇: HDU3939(毕达哥拉斯三元组的解)
- 下一篇: C语言/C++基础知识