標頭檔案不是可有可無的

2021-06-25 22:12:22 字數 1391 閱讀 6914

標頭檔案定義了資料結構,這大家都能體會到,因為不包含你要使用標頭檔案的話,編譯根本就通不過。標頭檔案的另乙個作用,宣告函式介面,作用似乎沒那麼大,因為編譯、連線都通過了,程式也能執行了,這不就行了嗎。下面我們用乙個例子說明這個問題。

#include #include int main(void)

int foo (int a)

此程式有嚴重的錯誤,但是如果我們用命令

$ gcc -c main.c
編譯的時候,沒有任何警告或出錯資訊。好,我們加上-wall選項:

$ gcc -c -wall main.c
main.c: in function `main':

main.c:8: warning: implicit declaration of function `foo'

這句implicit declaration of function可能是被程式設計師忽視最多的警告了。好,我們繼續忽視它,接下來連線也能通過:

$ gcc -o ex1 main.o
執行也沒有問題。 但你不覺得毛骨悚然嗎? 乙個嚴重的錯誤就這樣從你眼皮底下過去了。你的程式越來越複雜,這個警告混在一大堆編譯資訊裡,根本就注意不到了。直到某一天一些奇怪的問題出現了,你開始呼叫各種土槍洋炮來除錯程式…

其實,如果我們稍微尊重些編譯器,把函式的宣告加在main的前面,問題錯誤馬上顯現:

int foo (int a);

int main(void)

$ gcc -c -wall main.c
main.c: in function `main':

main.c:9: error: too many arguments to function `foo'

如果沒有關於被調函式的特定資訊,編譯器便假定在這個函式的呼叫時傳遞的引數型別和個數都是正確的,同時會假定函式返回乙個整數型別的值。對於那些返回值並非整數的函式而言,這種隱式宣告常常導致錯誤。這就是函式宣告的作用,它既告訴程式設計師如何呼叫乙個函式,也讓編譯器檢查呼叫與函式原型是否一致。有些人以為聯結器會檢查引數匹配的問題,連線不出錯就萬事大吉了,這是不對的。你想,引數是以暫存器或壓棧的方式傳遞的。編譯之後,引數型別和個數等資訊都已丟失,聯結器還能幫你查錯嗎? 它只是簡單地把名字相同的符號連線起來而已。

錯誤發現的越早越好

程式設計出現錯誤是不可避免的。錯誤發現的越早,修改的成本就越小。因此原則是:盡量讓錯誤暴露出來(例如嚴格的編譯選項、測試),而不是掩蓋或忽視它。 能在編譯時發現的錯誤,不要拖到執行時;能在編輯時發現的錯誤,不要拖到編譯時(許多編輯器的括號匹配、**補齊等功能就是為了減少這樣的錯誤)。

SEO可有可無的細節

都說seo細節決定成敗,這令本身建站經驗就不多,基礎較差的新手們望塵莫及,於是苦練div css 於是研究如何將頁面靜態化 於是恨不得把關鍵詞密度增加到100 讓關鍵詞立刻飆公升至榜首,於是 那麼,seo程式設計客棧是否一定要如此完美?答案是程式設計客棧否定的。當然,這些細節你運用熟練,對你的seo...

可有可無 正則 正則的基本概念

作用 處理字串 搜尋,替換,切分等 寫法 1.js物件風格 let re new regexp 正規表示式 選項 let re new regexp 1 3 9 d g global 全域性匹配,找到所有 2.perl風格 let re 正規表示式 選項 let re 1 3 9 d g d dig...

可有可無 正則 正規表示式 初學

import re demo data re.match r hello hello,武漢加油 print demo data 有物件則意味著正規表示式提取資料成功 執行結果 正則滿足條件提取資料成功,返回值是乙個物件,不滿足,none空 匹配單個字元 import re demo data re....