當C一個函式被宣告為void main();嘗試向它輸入一個引數(作為第一個也是唯一的引數)時不會導致編譯錯誤,為了防止它,函式可以宣告為void main(void);. 順便說一句,我認為這也適用于Objective C而不適用于C . 我Objective C指的是類外的功能。為什么是這樣?感謝您伸出援手。我想這類似于Fortran名稱以 i、j、k、l、m 或 n 開頭的變數是隱式integer型別的(除非您添加一個implicit none)。
編輯:Objective C 是否允許這樣做是因為與 C 具有更大的兼容性,還是類似于 C 擁有這個的原因?
注意:我保留了問題中的錯誤,因此不需要更改答案和評論。
另一個注意事項:正如@Steve Summit 和@matt(此處)所指出的,Objective-C 是 C 的嚴格超集,這意味著所有 C 代碼也是有效的 Objective-C 代碼,因此必須顯示有關函式的這種行為。
uj5u.com熱心網友回復:
因為函式原型不是預標準 C 的一部分,所以函式只能用空括號宣告:
extern double sin();
所有現有代碼都使用這種符號。如果這樣的代碼無效,或者意味著“零引數”,該標準就會失敗。
因此,在標準 C 中,這樣的函式宣告意味著“接受零個或多個引數的未定義串列”。該標準確實規定所有具有可變引數串列的函式必須在范圍內具有原型,并且原型將以, ...). 因此,使用空引數串列宣告的函式不是可變引數函式(而printf()它是可變引數)。
因為編譯器沒有被告知引數的數量和型別,所以無論呼叫中的引數如何,它都不會在呼叫函式時抱怨。
uj5u.com熱心網友回復:
在早期(ANSI 之前)C 中,編譯器不檢查函式定義與其呼叫之間函式引數的正確匹配。
我相信這樣做有兩個原因:
- 它使編譯器變得相當簡單
- C 一直是為單獨編譯而設計的,檢查翻譯單元(即跨多個源檔案)的一致性是一個更難的問題。
因此,在早期,確保函式的呼叫與其定義相匹配是程式員或單獨程式的責任lint。
對函式引數的松懈檢查也使可變引數函式成為printf可能。
無論如何,在原來的 C 中,當你寫
extern int f();
,你不是說“f是一個不接受任何引數并回傳的函式int”。你只是說“f是一個函式回傳int”。你沒有說任何關于爭論的事情。
基本上,早期 C 的型別系統甚至沒有記錄函式預期引數的方法。當單獨編譯發揮作用時尤其如此,因為聯結器幾乎僅根據它們的名稱來決議外部符號。
當然,C 通過引入函式原型改變了這一點。在 C 中,當您說 時extern int f();,您是在宣告一個顯式接受 0 個引數的函式。(還設計了一種“名稱修改”方案,其中包括讓聯結器在鏈接時進行一些一致性檢查。)
現在,這在舊 C 中都有點不足,ANSI C 引入的最大變化是在 C 中采用 C 的函式原型表示法。不過略有不同:為了保持兼容性,C 中的說法extern int f();必須解釋為意思是“函式回傳int并接受未指定的引數”。如果你想明確地說一個函式不帶引數,你必須(并且仍然必須)說extern int f(void);。
還有一種新的...表示法將函式顯式標記為接受可變引數,例如printf,并且開始擺脫int宣告中的“隱式”的程序。
總而言之,這是一個顯著的改進,盡管仍有一些漏洞。特別是,程式員仍有一些責任,即確保準確的函式原型始終在范圍內,以便編譯器可以檢查它們。另請參閱此問題。
另外兩個說明:您詢問了Objective C,但我對該語言一無所知,因此我無法解決這一點。您說對于沒有原型的函式,“嘗試向其輸入引數(作為第一個也是唯一的引數)不會導致編譯錯誤”,但實際上,您可以將任何數字或引數傳遞給此類一個函式,沒有錯誤。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/513001.html
標籤:C目标-c函数声明
