c語言中一個函數的聲明和定義有區別嗎?
聲明 定義
謝邀。程序的生成先是把每個源文件編譯成.o,然後再把幾個.o鏈接生成程序。一個源文件里只要聲明了函數,就可以正常編譯成.o,鏈接的時候才會去綁定函數定義。所以你可以在源文件a.c里聲明一個函數,在b.c里定義(實現)它。
函數聲明引入了一個名字——代表一個函數,並且可選的,指明函數的參數列表,可以出現在文件作用域和塊作用域中。
函數定義將函數體和函數名及參數關聯起來,並且只能出現在文件作用域中
參見Function declarations
Function definitions
大神回答的都很簡單易懂!我覺得函數聲明,就是告訴編譯器這兒有個函數,它叫XXX,參數是XXX,返回值是XXX,至於函數怎麼實現,鬼知道!函數定義,告訴編譯器,不光它叫XXX,參數是XXX,返回值是XXX,還有實現的代碼也告訴編譯器了。
好吧,我又來暴露我的智商了,哈哈!
菜鳥一答:當函數定義在函數調用處後時,
當函數定義在另一個文件中時,
(兩份代碼是可以編譯通過的)注釋那行代碼開始,就告訴了編譯器,從此刻開始,我知道有個swap()「此處函數聲明與函數定義不同就是為了刻意說明:函數聲明只是告訴編譯器,我其它地方有這玩意兒,從此處(聲明)開始,你就可以去調用這玩意兒,至於是不是真的有,呵呵」,但我不確定這個swap()的具體參數。
當我去調用swap(a,b)時,編譯器就猜測函數聲明swap()是我們函數定義中的void swap(int,int)
。當然,函數聲明和函數定義不同是很不好的習慣,這裡我只是刻意說明:函數聲明只是為了告訴編譯器,我是有這個玩意兒的(如果沒有,只要你不調用也不會報錯),從此刻後,你就可以調用我聲明的這個玩意兒了。
當然,我的回答不好,舉例也不恰當。如有錯誤,誠望指正 ^▽^
好答案詳見@潘安仁大大的回答這個跟C語言的編譯機制有關,前面已經有人說了。
小明,你去把窗子開一下。(誰是小明?報錯了。)
所以要寫成:
小明是身份證號為XXXXX的同學。//定義
小明,你去把窗子開一下。 //調用
或者寫成:
有一個小明 //聲明
小明,你去把窗子開一下。 //調用
小明是身份證號為XXXXX的同學。 //定義
我通常稱之為函數的聲明與實現。
聲明就是告訴使用者函數名是什麼,返回值是什麼,參數列表又是什麼。
實現就是告訴機器如何使用參數列表,怎樣去完成一些功能,又如何通過返回值反饋函數執行情況。不知道對你有沒有幫助,認識比較膚淺,見笑了如果類比書的構造,應該就很好理解了吧。
函數聲明好比書的目錄,只有內容的標題,沒有實際的內容。並且類似一些書在結尾處設有字母序的內容索引,函數聲明同樣可以被多次書寫。
函數定義自然類比為書的實際內容。作者應該不會在書中反覆出現相同的內容,所以函數定義當然只能有一次了。
@孫明琦聚聚說的很隊,然而卻不是新人最想要的答案。本質上這是歷史遺留的包袱。當年c語言設計的時候,內存太小以至於無法容納整個文件,只能one pass讀到哪兒解析到哪兒,「讀完即忘」。所以人為引入了限制:所有的函數必須先聲明再使用(隱式聲明另說,此處不表),否則必須要搜索整個文件去找函數聲明,開銷無法接受。代價便是造成了邏輯上的割裂,許多新手都會在「聲明」「鏈接」「定義」上花一番力氣。
現代語言放寬了這個限制,比如java這種,你可以以任意順序寫函數體,並且互相調用,沒有前置聲明這種workaround。然而c++為了兼容性不得已保留了這種簡陋脆弱的機制,順便也就繼承了頭文件這種歷史古董。
如果是新人上手,建議讀@陳碩先生的博文(還是書?忘了),講解比較易讀。如果想深入,可以讀程序員的自我修養一書,那邊更為詳細。聲明和定義的區別問題無外乎
有一種叫長頸鹿的動物和長頸鹿是有長長脖子的哺乳動物的區別,前者告訴你存在一樣事物,但是具體怎麼樣不知道,後者具體的告訴你這就是長頸鹿,肉質如何等等信息。一千個人眼中有一千個哈姆雷特哈姆雷特是聲明,眼中的漢姆雷特是定義從C語言編譯器的角度來看,函數聲明只是一種協議,它告訴了調用者在調用這個函數之前需要給他什麼參數,一般參數是通過寄存器或者壓棧的方式傳給被調用函數的,具體這些參數如何使用以及返回什麼值到相應的寄存器里返回給調用者則是定義所描述的。
說白了就是看露天電影搬個馬扎佔位子,馬紮上寫的是你名字,電影沒開始人先不過去,回家把飯吃完先…
當然有。通俗的講,申明就是告訴後面代碼,我有一個這個名字的函數,而定義,就是實現這個函數的功能的代碼段。函數的申明要出現在任何調用這個函數的語句之前,不過如果函數的定義出現在調用之前,申明可以省略,就是函數定義代替了申明。同時,函數申明時候形參可以只給類型不給名字,但是函數定義時,必須給出形參類型和名字
C語言中一切的傳遞都是值傳遞。
1聲明,告訴你在那個值對應的地方有一個可用的函數
2定義,實實在在的在那裡寫一個函數
(實際過程並不如上,但是是這個意思。)推薦閱讀:
※C++中生成隨機數的問題?
※*a.b()是什麼意思,運算符順序是怎麼看的?
※CS、360、這些軟體的根目錄下有很多不同類型的文件。在沒有VS、JDK這些「程序設計語言」的「支持?
※能不能用c#和c/c++以及其他語言寫一個完整的IDE(類似visual studio)?
※圖中的最長路徑問題怎麼算?