通過一些學習,相信大家對C語言和編程都有所了解。但是,C語言學習是否如大家所想那么簡單易學呢? 其實不盡然,有時候我們往往低估了這門學問。本篇文章展示了14個C語言的迷題以及答案,代碼應該是足夠清楚的,而且我也相信有相當?shù)囊恍├涌赡苁俏覀內(nèi)粘9ぷ骺赡軙姷玫降?。通過這些迷題,希望你能更了解C語言。如果你不看答案,不知道是否有把握回答各個謎題?讓我們來試試。

1、下面的程序并不見得會輸出 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是不是同設備描述符。stdout是塊設備,stderr則不是。對于塊設備,只有當下面幾種情況下才會被輸入,1)遇到回車,2)緩沖區(qū)滿,3)flush被調(diào)用。而stderr則不會。

2、下面的程序看起來是正常的,使用了一個逗號表達式來做初始化。可惜這段程序是有問題的。你知道為什么呢?

#include

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

3、下面,我們再來看一個交叉編譯的事情,下面的兩個文件可以編譯通過嗎?如果可以通過,結果是什么?

file1.c

int arr[80];
file2.c

extern int *arr;
int main()
{
arr[1] = 100;
printf("%d\n", arr[1]);
return 0;
}
參考答案:該程序可以編譯通過,但運行時會出錯。為什么呢?原因是,在另一個文件中用 extern int *arr來外部聲明一個數(shù)組并不能得到實際的期望值,因為他們的類型并不匹配。所以導致指針實際并沒有指向那個數(shù)組。注意:一個指向數(shù)組的指針,并不等于一個數(shù)組。修改:extern int arr[]。(參考:ISO C語言 6.5.4.2 節(jié))

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

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

5、下面的程序會輸出什么?

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

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

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

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

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

延伸閱讀

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