在學習C語言函數的時候,老師總會告訴咱們函數要寫聲明,而後再定義。這是個穩健的作法。等我本身學習了其餘高級語言之後,回頭再來寫C,忽然就以爲函數要寫聲明有點麻煩。無心間發現有一次函數沒寫聲明竟然編譯(GCC 5.3)也經過了,並且都沒有報錯。因而想起來要好好研究一下這個C語言的函數聲明何時能夠不寫,何時必須寫。函數
這其實談不上是技術性問題。就好像討論i++ 和++i那麼無聊。這都是編譯器致使的語法問題。說他們都是歷史遺留問題都不爲過。學習
可是在C語言學習過程當中,你不得不去把這些鬼問題弄清楚。這樣在之後面對千奇百怪的C語言代碼的時候才能作到心裏毫無波動。編譯器
有的書上是這麼說的,若是函數定義放在main函數前面,能夠不用寫聲明。若是函數放在main函數後面,就規定要寫函數聲明。這麼說沒毛病。不過我本身又無聊地嘗試了一下,發現了更準確的規則。若是在函數定義在這個函數調用以前,就不須要寫聲明。不然就要寫聲明。編譯
關於這個函數定義的位置其實也是個能夠摸索的事情。C語言不容許在一個函數中定義其餘函數,可是main函數除外。我發現能夠在main函數中定義函數。若是你在main函數中定義函數,若是在函數被調用以前就定義了這個函數,那麼就不須要聲明瞭,這樣編譯連警告都沒有,若是你在main函數中定義函數,而函數定義的位置比函數調用還要後,那麼就沒法經過編譯了。進一步作無聊事情,假設咱們在函數調用語句以後再定義函數,這個條件下有兩種狀況(單文件下),在main函數外面定義這個函數,編譯會出警告信息,可是能夠經過。若是是在main函數裏面定義的。那就編譯就會有警告+錯誤信息。語法
一樣的關於函數聲明的位置也是能夠無聊地摸索一下。由於函數聲明能夠放在main函數外面,也能夠放在main函數裏面。我說能夠放在main函數外面確定說的是放在main函數上面。這個是正常作法。有的書會把聲明放在main函數裏面,也是能夠的。只要只要聲明函數的位置在函數調用前面就OK了。由此能夠弱弱地推測出,C編譯器是看到了聲明,而後去尋找對應函數定義進行編譯。若是沒有聲明,可是函數定義寫在函數調用前面,那這個函數定義也比函數調用的代碼先一步編譯了也沒問題了。這個弱弱地推測,就能夠解釋我以上無聊的實驗結果了。技術
當時除了我這樣無聊的初學者,誰會一直在main函數裏寫函數呢?語言