通過(guò)一些學(xué)習(xí),相信大家對(duì)C語(yǔ)言和編程都有所了解。但是,C語(yǔ)言學(xué)習(xí)是否如大家所想那么簡(jiǎn)單易學(xué)呢? 其實(shí)不盡然,有時(shí)候我們往往低估了這門(mén)學(xué)問(wèn)。本篇文章展示了14個(gè)C語(yǔ)言的迷題以及答案,代碼應(yīng)該是足夠清楚的,而且我也相信有相當(dāng)?shù)囊恍├涌赡苁俏覀內(nèi)粘9ぷ骺赡軙?huì)見(jiàn)得到的。通過(guò)這些迷題,希望你能更了解C語(yǔ)言。如果你不看答案,不知道是否有把握回答各個(gè)謎題?讓我們來(lái)試試。

1、下面的程序并不見(jiàn)得會(huì)輸出 hello-std-out,你知道為什么嗎?

#include
#include
int main()
{
while(1)
{
fprintf(stdout,"hello-std-out");
fprintf(stderr,"hello-std-err");
sleep(1);
}
return 0;
}
參考答案:stdout和stderr是不是同設(shè)備描述符。stdout是塊設(shè)備,stderr則不是。對(duì)于塊設(shè)備,只有當(dāng)下面幾種情況下才會(huì)被輸入,1)遇到回車(chē),2)緩沖區(qū)滿,3)flush被調(diào)用。而stderr則不會(huì)。

2、下面的程序看起來(lái)是正常的,使用了一個(gè)逗號(hào)表達(dá)式來(lái)做初始化??上н@段程序是有問(wèn)題的。你知道為什么呢?

#include

int main()
{
int a = 1,2;
printf("a : %d\n",a);
return 0;
}
參考答案:這個(gè)程序會(huì)得到編譯出錯(cuò)(語(yǔ)法出錯(cuò)),逗號(hào)表達(dá)式是沒(méi)錯(cuò),可是在初始化和變量聲明時(shí),逗號(hào)并不是逗號(hào)表達(dá)式的意義。這點(diǎn)要區(qū)分,要修改上面這個(gè)程序,你需要加上括號(hào): int a = (1,2);

3、下面,我們?cè)賮?lái)看一個(gè)交叉編譯的事情,下面的兩個(gè)文件可以編譯通過(guò)嗎?如果可以通過(guò),結(jié)果是什么?

file1.c

int arr[80];
file2.c

extern int *arr;
int main()
{
arr[1] = 100;
printf("%d\n", arr[1]);
return 0;
}
參考答案:該程序可以編譯通過(guò),但運(yùn)行時(shí)會(huì)出錯(cuò)。為什么呢?原因是,在另一個(gè)文件中用 extern int *arr來(lái)外部聲明一個(gè)數(shù)組并不能得到實(shí)際的期望值,因?yàn)樗麄兊念愋筒⒉黄ヅ?。所以?dǎo)致指針實(shí)際并沒(méi)有指向那個(gè)數(shù)組。注意:一個(gè)指向數(shù)組的指針,并不等于一個(gè)數(shù)組。修改:extern int arr[]。(參考:ISO C語(yǔ)言 6.5.4.2 節(jié))

4、下面的程序會(huì)有什么樣的輸出呢?

#include
int main()
{
int i=43;
printf("%d\n",printf("%d",printf("%d",i)));
return 0;
}
參考答案:程序會(huì)輸出4321,你知道為什么嗎?要知道為什么,你需要知道printf的返回值是什么。printf返回值是輸出的字符個(gè)數(shù)。

5、下面的程序會(huì)輸出什么?

#include
int main()
{
float a = 12.5;
printf("%d\n", a);
printf("%d\n", (int)a);
printf("%d\n", *(int *)&a);
return 0;
}
參考答案:該項(xiàng)程序輸出如下所示, 0 12 1095237632 原因是:浮點(diǎn)數(shù)是4個(gè)字節(jié),12.5f 轉(zhuǎn)成二進(jìn)制是:01000001010010000000000000000000,十六進(jìn)制是:0x41480000,十進(jìn)制是:1095237632。所以,第二和第三個(gè)輸出相信大家也知道是為什么了。而對(duì)于第一個(gè),為什么會(huì)輸出0,我們需要了解一下float和double的內(nèi)存布局,如下:

float: 1位符號(hào)位(s)、8位指數(shù)(e),23位尾數(shù)(m,共32位)
double: 1位符號(hào)位(s)、11位指數(shù)(e),52位尾數(shù)(m,共64位)
然后,我們還需要了解一下printf由于類型不匹配,所以,會(huì)把float直接轉(zhuǎn)成double,注意,12.5的float和double的內(nèi)存二進(jìn)制完全不一樣。別忘了在x86芯片下使用是的反字節(jié)序,高位字節(jié)和低位字位要反過(guò)來(lái)。所以:

float版:0x41480000 (在內(nèi)存中是:00 00 48 41)
double版:0x4029000000000000 (在內(nèi)存中是:00 00 00 00 00 00 29 40)
而我們的%d要求是一個(gè)4字節(jié)的int,對(duì)于double的內(nèi)存布局,我們可以看到前四個(gè)字節(jié)是00,所以輸出自然是0了。 這個(gè)示例向我們說(shuō)明printf并不是類型安全的,這就是為什么C++要引如cout的原因了。

6、請(qǐng)說(shuō)出下面的程序輸出是多少?并解釋為什么?(注意,該程序并不會(huì)輸出 "b is 20")

#include
int main()
{
int a=1;
switch(a)
{
int b=20;
case 1:
printf("b is %d\n",b);
break;

延伸閱讀

學(xué)習(xí)是年輕人改變自己的最好方式-Java培訓(xùn),做最負(fù)責(zé)任的教育,學(xué)習(xí)改變命運(yùn),軟件學(xué)習(xí),再就業(yè),大學(xué)生如何就業(yè),幫大學(xué)生找到好工作,lphotoshop培訓(xùn),電腦培訓(xùn),電腦維修培訓(xùn),移動(dòng)軟件開(kāi)發(fā)培訓(xùn),網(wǎng)站設(shè)計(jì)培訓(xùn),網(wǎng)站建設(shè)培訓(xùn)學(xué)習(xí)是年輕人改變自己的最好方式