關於ANSI C函數聲明,這是如何改進舊的K & R風格?我知道他們之間的差異,我只是想知道使用舊風格會產生什麼問題,以及新風格如何改進。ANSI C函數如何聲明對舊Kernigan和Ritchie風格的改進?
回答
舊式函數聲明,特別是不允許編譯時檢查調用。
例如:
int func(x, y)
char *x;
double y;
{
/* ... */
}
...
func(10, 20);
當編譯器看到的號召,它不知道該類型的功能func
的參數,所以它可以」 t診斷錯誤。
相比之下:
int better_func(char *x, double y) {
/* ... */
}
...
better_func(10, 20);
將導致編譯錯誤信息(或至少一個警告)。
另一個改進:原型使得有可能具有的功能與float
類型的參數,以及比int
窄整數類型(3種char
類型和兩個short
類型)的。沒有原型,float
被提升爲double
,窄整數類型被提升爲int
或unsigned int
。使用原型,float
參數作爲float
傳遞(除非函數是可變參數,如printf
,在這種情況下舊規則適用於可變參數)。
的C Rationale文件討論這部分6.7.5.3,可能比我更好:
的函數原型機制是最有益的補充 C語言之一。當然,這個功能在過去25年的Algol派生語言的許多 中都有先例。標準中採用的特殊形式 大部分基於C++。
函數原型提供了強大的轉換時間錯誤 檢測能力。在沒有原型的傳統C實踐中,翻譯器在調用另一個 源文件中聲明的函數時檢測錯誤(錯誤的 參數數量或類型)非常困難。在運行時間 或通過使用輔助軟件工具發現此類錯誤的檢測。
在函數中的函數原型的範圍不調用,整數 參數具有施加的整數促銷和浮子 參數被加寬以雙。在這樣的電話 中不可能通過未轉換的char或float參數。函數 原型使程序員可以顯式控制參數類型轉換,因此通常不合適的和有時效率低下的自變量缺省擴展規則可能會被實現所抑制,例如 。
還有更多;去閱讀它。
有趣的是,K&R風格更符合C聲明的基本思想; 「聲明模仿使用」。 – bames53
爲什麼編譯器檢測不到K&R式函數的類型不匹配?所有的類型信息仍然存在。 – templatetypedef
@templatetypedef:不一定。舊式非原型函數*聲明*不包含函數的主體,因此它不提供參數類型信息。例如:'some_header.h'中的'int func();'。完整的*定義*確實提供了這些信息,但是(a)它可能不在同一個源文件中,並且(b)編譯器不需要使用它,即使它是。使用無效參數調用非原型函數具有未定義的行爲;它不需要被診斷。 –
以K & R A非限定函數聲明看起來如下
int foo();
,並介紹接受未指定數目的參數的函數。這種聲明風格的問題很明顯:它既沒有指定參數的數量,也沒有指定它們的類型。編譯器沒有辦法根據調用點處的參數數量或類型來檢查調用的正確性。在參數類型與預期參數類型不匹配的情況下,編譯器無法執行參數類型轉換或問題和錯誤消息。
函數聲明,其被用作的功能定義以K &一個部分R看起來如下
int foo(a, b)
int a;
char b;
{ ...
它指定的參數的數量,但仍沒有指定其類型。此外,即使參數的數量似乎通過此聲明公開,它仍然正式聲明foo
的方式與int foo();
的方式相同,這意味着將其稱爲foo(1, 2, 3, 4, 5)
仍然不構成約束違規。
新樣式,即帶原型的聲明比較好,原因很明顯:它公開了參數的數量和類型。它強制編譯器檢查調用的有效性(關於參數的數量和類型)。它允許編譯器執行從參數類型到參數類型的隱式類型轉換。
原型聲明提供了其他一些不太明顯的好處。由於函數參數的數量和類型對調用者和函數本身都是精確已知的,因此可以選擇在調用點傳遞參數(調用約定)的最有效的方法,而不必查看函數定義。如果沒有這些信息,所有功能都必須遵循一個預定義的「一刀切」調用約定。
- 1. JavaScript函數聲明風格
- 2. C風格struct聲明
- 3. 風格:內聯函數聲明中
- 4. C風格的聲明將被折舊爲我循環
- 5. 函數聲明:K&R與ANSI
- 6. 如何改進c風格函數回調系統?
- 7. C++ * VS和函數聲明
- 8. 在C/C++中聲明Unix風格
- 9. 中聲明,如果聲明(ANSI C)可變
- 10. C++函數聲明
- 11. ANSI C和函數重載
- 12. 如何在Objective-C內聯中聲明好的舊C數組?
- 13. 如何在c中聲明和定義objective-c中的函數?
- 14. C++中的函數和變量聲明
- 15. C++中的函數聲明
- 16. C++如何找到函數聲明
- 17. 如何聲明extern(「C」)const函數?
- 18. Objective-C函數聲明如何工作?
- 19. 角度js控制器中的函數聲明風格
- 20. C++如何聲明函數返回對象的向量
- 21. 如何在Python中聲明變量類型,C風格
- 22. C語言入門:函數聲明
- 23. 「{」缺少函數頭(舊式格式列表) - 預期聲明
- 24. C++前向聲明和純虛函數
- 25. C++前向聲明和析構函數
- 26. C++循環和聲明函數
- 27. ANSI-C語法 - 數組聲明如[*]等alii
- 28. C++風格約定:類聲明中的參數名稱
- 29. 和的typedef函數聲明
- 30. 如何聲明的NSString * C風格的數組作爲全局變量
我看到有一個投票來關閉它。我同意這個問題可能是模糊的,但我相信有一個具體的答案(見我的)。 –