通過一些學習,相信大家對C語言和編程都有所了解。但是,C語言學習是否如大家所想那么簡單易學呢? 其實不盡然,有時候我們往往低估了這門學問。本篇文章展示了14個C語言的迷題以及答案,代碼應該是足夠清楚的,而且我也相信有相當?shù)囊恍├涌赡苁俏覀內粘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被調用。而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 轉成二進制是:01000001010010000000000000000000,十六進制是:0x41480000,十進制是:1095237632。所以,第二和第三個輸出相信大家也知道是為什么了。而對于第一個,為什么會輸出0,我們需要了解一下float和double的內存布局,如下:
float: 1位符號位(s)、8位指數(shù)(e),23位尾數(shù)(m,共32位)
double: 1位符號位(s)、11位指數(shù)(e),52位尾數(shù)(m,共64位)
然后,我們還需要了解一下printf由于類型不匹配,所以,會把float直接轉成double,注意,12.5的float和double的內存二進制完全不一樣。別忘了在x86芯片下使用是的反字節(jié)序,高位字節(jié)和低位字位要反過來。所以:
float版:0x41480000 (在內存中是:00 00 48 41)
double版:0x4029000000000000 (在內存中是:00 00 00 00 00 00 29 40)
而我們的%d要求是一個4字節(jié)的int,對于double的內存布局,我們可以看到前四個字節(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;
延伸閱讀
- 5G時代,會是國產操作系統(tǒng)突破的契機嗎? 2018-12-26
- 8年時間,什么叫從0到1?雷軍的小米已注定成傳奇! 2018-12-26
- Visual Studio 20周年軟件趨勢隨想 2017-06-28
- Kotlin語言和Java語言100%互通 2017-05-19
- 微信小程序正式上線 2017-03-06
- 如何組建測試團隊? 2024-03-26
- 2016年收入最高的5個編程語言 2016-10-23
- TIOBE 2016年4月編程語言排行榜:Visual Basic即將出局 2016-04-13
- 甲骨文就 Java 侵權案向谷歌索賠 93 億美元 2016-04-11
- AlphaGo最終局戰(zhàn)勝李世石 人機大戰(zhàn)總比分1:4 2016-09-04