日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[C语言]为什么要有include?——从Hello World说起

發布時間:2023/12/13 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [C语言]为什么要有include?——从Hello World说起 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文轉自:http://mp.weixin.qq.com/s?__biz=MzAwOTgzNzQyMw==&mid=433613487&idx=1&sn=803995d612faadce6e4418789a6a65a8&scene=2&srcid=0312ElIT9UmR0ZygPGHxDxs2&from=timeline&isappinstalled=0#wechat_redirect


大家都會寫的Hello World程序長這個模樣:

#include <stdio.h>

int main( ){

? ? printf("Hello world!\n");

? ? return 0;

}

看,關鍵的就是第三行,調用了printf函數,在屏幕上打印了偉大的"Hello world!"。第一行那個include是個啥?我聽到過這樣的解釋:“include是包含的意思,尖括號里的stdio.h是標準輸入輸出函數庫文件,這個文件里有printf的代碼,把這個代碼包含到main函數之前,就可以使用printf函數進行打印啦~” —— 打住!這種話騙騙剛開始學習C語言的小孩還可以,怎么可以用來騙大學生呢?現在請大家把第一行刪除,重新編譯運行看看?奇葩,居然依然可以順利執行!但是細心的孩紙會發現,這次盡管成功運行了,但是編譯時有一條警告(Warning)信息,如果你的編譯器是gcc的話,這條Warning的樣子應該是:

warning: implicitly declaring library function 'printf' with type 'int (const char *, ...)'

What?這是咩意思?冷靜一下,請大家不要一看到英文就頭皮發麻、六神無主、舉手問老師。至少可以翻翻詞典嘛,前兩個詞就很明白了:隱含聲明。先不解釋,我們繼續修改代碼,變成這樣:

int main(){

? ? printf("Hello world!\n");

? ? hehe(3, 5);

? ? return 0;

}

然后大家就笑了:這肯定不能運行了吧?那個hehe()函數根本就不存在嘛!沒錯,這個確實不能運行了,但是依然可以編譯。據我所知大家都很偷懶,編好程序之后都是直接在集成開發環境(IDE)中直接點運行按鈕的,那么這次請點擊編譯按鈕,或者在命令行中手動輸入編譯命令,我們就能發現,又多了一條Warning:

?warning: implicit declaration of function 'haha' is invalid in C99

又是“隱含聲明”!

為什么printf和hehe兩個函數都提示“隱含聲明”,前一個能運行,而后一個不行呢?我們從頭梳理:

首先,了解一下什么叫做函數的“聲明”(或者叫“原型”)。函數聲明就是描述一下這個函數長什么樣子,而不描述這個函數具體怎么實現的。舉個例子: void hehe(int, int); 就是一個函數的聲明,注意,括號后面是一個分號,而不是一對花括號{ },而且括號里面只寫了參量類型,沒有寫參量名啊。函數的聲明是給編譯器看的,當編譯器看到上面那個聲明,她就會知道:哦,有一個函數,名字叫hehe,帶有兩個整型參量,沒有返回值。至于這個函數具體是干什么的,編譯器不關心~ 同樣,編譯器也不關心這個函數的兩個參量叫什么名字,所以列表中可以只寫類型,不寫參量名。

然后,我們大家都學過:C語言規范要求在調用函數之前,必須出現該函數的聲明。這是為什么呢?是為了讓編譯器高興啊。編譯器從上往下檢查代碼,當看到函數調用時,就會對照此前出現過的聲明檢查一下調用是否符合聲明的格式。如果冷不丁地看到一個函數調用,但在此之前沒見到過該函數的聲明,編譯器就郁悶了,她的內心活動是:“這函數,沒見過、不認識啊,所以,這么個調用法,到底是正確呢?還是錯誤呢?我不知道啊!我作為一個編譯器,不知道這句是正確還是錯誤,多沒面子啊!”這時候,編譯器能報一個“錯誤”(Error)嗎?不能。但是編譯器究竟還是負責人的,她覺得這句話可能會有問題,因此給了一個警告,讓程序員自己看著辦……

接下來,分析一下為什么printf沒有聲明,能夠正確執行。大家可以翻翻前面我說的那個“騙小孩子”的話,stdio.h里面并沒有printf的實現代碼,而是有printf的聲明(請在自己計算機中自行搜索stdio.h,并打開文件查找printf,看看是如何聲明的)。printf的實現代碼,是在C標準庫的其它文件中(隨著OS不同,具體文件也不同)的,而且是編譯過之后的代碼,不像stdio.h中,都是“源代碼”。如果把include那行刪去,編譯器在看到printf調用時,就不知道printf應該長成啥樣,所以不知道調用是否正確,給了一個警告。但是在編譯之后的“鏈接”過程,C標準庫就被鏈接到程序中了,所以只要printf的調用寫得沒有錯誤,就可以正確運行。

最后,分析為什么添加hehe(3,5)之后能編譯,但是不能正確執行。道理與上面是一樣的,編譯器看到hehe(3,5)的調用,因為沒有聲明過,她不認識這函數啊,所以,不能報錯,只能給一個警告。接下來的步驟,鏈接,C標準庫依然被鏈接到了程序中,但是……但是……但是……hehe( )是個什么鬼?這函數根本就不在C標準庫中好嗎!而且程序員自己所寫的程序中也沒有提供hehe( )的實現代碼啊!所以鏈接失敗……

哦,似乎忘了說,C代碼寫好之后要想運行,得經過這么幾步:(1)對每個源文件分別進行編譯(compile),各自生成目標代碼(擴展名可能是.obj .o 或者其它)(2)把編譯過后生成的這些目標代碼以及C標準庫鏈接起來(link),生成可運行的程序。

最后放一條冷笑話:某個峽谷上方架有一座橋,一次暴風雨過后,橋斷了,負責維護的工人一時間還來不及修復,于是在橋頭插了一塊牌子,上面寫道:“Warning! The bridge is broken!” 結果呢?還是有好多人毅然走上斷橋,摔到了峽谷里。工人們感到很奇怪,于是到了谷底查看,發現摔到谷底的全都是程序員。

上面的笑話沒看懂?沒關系,作為程序員,記住下面這一點就行了:絕不放過任何一個warning,否則可能會死得很慘~~~

總結

以上是生活随笔為你收集整理的[C语言]为什么要有include?——从Hello World说起的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。