我只想知道C是否支持加載? 由於我們使用printf等系統函數,其參數不同。 幫我出來C支持重載嗎?
C支持重載嗎?
回答
不,C不支持任何形式的超載(除非你是內置運營商重載已經是事實,是的超載一種形式)。
printf
使用稱爲varargs的功能工作。你讓一個呼叫看起來像它可能過載:
printf("%d", 12); // int overload?
printf("%s", "hi"); // char* overload?
其實事實並非如此。只有一個printf函數,但編譯器使用特殊的調用約定來調用它,其中提供的任何參數都按順序放置在堆棧上[*]。 printf(或vprintf)檢查格式字符串並使用它來計算出如何讀取這些參數。這就是爲什麼printf的是不是類型安全:
char *format = "%d";
printf(format, "hi"); // undefined behaviour, no diagnostic required.
[*]標準實際上並不說他們在棧中傳遞,或提棧可言,但是這是自然的實現。
我不能爲所有編譯器說話,但是一旦函數返回,與我一起工作的那個調用者就會調整它所推送的參數的堆棧。對於我來說,這對於可變參數函數來說似乎是一個好主意 - 比使函數從堆棧中彈出它們更安全。 – tomlogic 2010-02-28 17:42:14
你說得對,實際上cdecl的調用約定就是這樣的(調用者負責堆棧清理);我刪除了評論以避免混淆其他讀者。真正的問題在於scanf,如果提供的格式字符串不正確,可能會將數據寫入內存中的隨機位置(從堆棧中取出)。 – 2010-02-28 17:47:31
C1X將支持通過類型通用表達式和宏 – Spudd86 2011-07-22 22:30:11
不,C不支持重載,但支持Variadic functions。 printf是變量函數的一個例子。
C不支持重載。 (顯然,即使它確實如此,它們也不會將它用於printf:對於每種可能的組合類型,您都需要printf!)
printf使用varargs。
不,C不支持重載。如果你想實現類似於C++的重載,你將不得不手動地調整你的函數名稱,使用某種一致的約定。例如:
int myModule_myFunction_add();
int myModule_myFunction_add_int(int);
int myModule_myFunction_add_char_int(char, int);
int myModule_myFunction_add_pMyStruct_int(MyStruct*, int);
這一切都取決於您如何定義「支持」。
顯然,C語言提供重載運算核心語言中,因爲使用C大多數運營商都重載功能:您可以使用二進制+
與int
,long
與指針類型。
然而,在同一時間C不允許你創建你自己的重載函數和C標準庫也有訴諸不同名稱的功能與不同類型(如abs
,fabs
,labs
等使用)。
換句話說,C有一定程度的重載編碼爲核心語言,但標準庫和用戶都不允許自己重載。
沒有c不支持函數重載。 但是如果你使用g ++(一個C++編譯器),你可以把它編譯/工作。
-1,如果你正在編寫C你應該使用C編譯器。 – 2010-02-28 18:51:08
借調。如果您使用C++編譯器來編譯代碼,那麼您正在撰寫的是C++代碼,而不是C代碼。特別是如果您使用C++中不在C中的功能,例如功能重載! – 2010-02-28 21:40:37
認真-2哈哈 – chinmaya 2010-03-01 02:14:20
不是直接的,這不是printf
的工作方式,但如果類型大小不同,則可以使用宏創建等效的重載函數。 C99標準的tgmath.h中的類型通用數學函數可以用這種方式實現。
C標準沒有規定操作符重載;由於許多構建系統無法容納具有相同名稱的多個功能,所以添加它的建議已被拒絕。雖然C++可以通過例如有
void foo(int);
int foo(char*);
long foo(char *, char **);
編譯成一個名爲類似v__foo_i,i__foo_pc和l__foo_pc_ppc [編譯器使用不同的命名規則的功能,雖然C++標準禁止在標識符利用內部雙下劃線的,以使編譯器給東西的名字像上面沒有衝突]。 C標準的作者不希望任何編譯器改變命名約定以允許重載,所以他們不提供它。
編譯器將允許重載靜態和內聯函數而不會產生命名問題;這將在實際中是一樣允許外部聯性功能超載爲有用的,因爲人們可以具有一個頭文件:
void foo_zz1(int);
int foo_zz2(char*);
long foo_zz3(char *, char **);
inline void foo(int x) { foo_zz1(x); }
inline int foo(char* st) { foo_zz2(st); }
long foo(char *p1, char **p2) { foo_zz3(p1,p2); }
我記得在看爲C和C++之間的混合的嵌入式編譯器,其支持上述的作爲一個非標準的延伸,但我對細節並不積極。無論如何,即使一些C編譯器支持重載沒有外部鏈接的函數的重載,C14也不支持它,但我不知道(不幸的是)(不幸)有任何積極的努力將這種特性添加到未來的C標準中。
儘管如此,GCC可以通過使用宏來支持一種重載形式,這種形式的重載不會直接在具有運算符重載的語言中被支持。 GCC包含一個內在的特徵,它將確定一個表達式是否可以作爲編譯時常量進行評估。使用這個內在的,可以寫一個宏,它可以根據參數以不同的方式(包括通過調用函數)來評估表達式。在某些情況下,如果給定編譯時常量參數,公式將作爲編譯時常量進行計算,但在給定可變參數時會產生可怕的混亂情況。作爲一個簡單的例子,假設有人希望位反轉一個32位的值。如果該值是恆定的,一個能做到這一點通過:
#define nyb_swap(x) \
((((x) & 1)<<3) | (((x) & 2)<<1) | (((x) & 4)>>1) | ((((x) & 8)>>3))
#define byte_swap(x) \
((nyb_swap(x)<<4) | nyb_swap((x) >> 4))
#define word_swap(x) \
((byte_swap(x)<<24) | (byte_swap((x) >> 8)<<16) | \
(byte_swap((x) >> 16)<<8) | (byte_swap((x) >> 24)))
而像uint32_t x=word_swap(0x12345678);
表達只會加載x
與0×87654321。另一方面,如果該值不是一個常數,結果將是可怕的:像uint32_t y=word_swap(x);
這樣的表達式可能會產生許多指令;使用部分展開的循環調用函數幾乎同樣快,但更緊湊。另一方面,使用循環會阻止將結果視爲編譯時常量。
使用GCC,可以定義一個宏,這將既可以使用固定收益宏,如果在恆定的,或者給一個變量時調用一個函數:
#define wswap(x) \
(__builtin_constant_p((x)) ? word_swap((x)) : word_swap_func((x))
這種方法不能做的一切類型基於重載可以做,但它可以做很多事情,重載不能。
- 1. EL支持重載方法嗎?
- 2. printf支持函數重載在C中?
- 3. GNU Global支持objective-c嗎?
- 4. C支持基礎類嗎?
- 5. C#支持程序嗎?
- 6. Objective-C支持traits/mixins嗎?
- 7. MonoTouch支持C#動態嗎?
- 8. Php支持方法重載
- 9. Objective-C不支持重載方法Objective-C
- 10. 可移植類庫支持Interlocked.Read和'long'重載嗎?
- 11. Java 8支持多重繼承嗎?
- 12. psexec支持輸入重定向嗎?
- 13. C支持範圍解析嗎?
- 14. VS2008有一些C++ 0x的支持嗎?
- 15. C正則表達式支持lookahead嗎?
- 16. Cython支持C++ 11容器嗎?
- 17. Realm中會有C++/Qt支持嗎?
- 18. Windows 8桌面支持C++/cli嗎?
- 19. C支持可選的空參數嗎?
- 20. 確實visual C++ 6.0支持unicode嗎?
- 21. 微軟會繼續支持C++/CLI嗎?
- 22. Visual C++支持循環不切換嗎?
- 23. 你支付Subversion支持嗎?
- 24. 不支持linux 3.7.1支持ext2嗎?
- 25. Delphi支持哪些操作符重載?
- 26. 重載可選陣列支持 - Java
- 27. 是否dwscript支持運算符重載
- 28. Java是否支持運算符重載?
- 29. 除C++外,哪些編程語言支持運算符重載?
- 30. 爲什麼客觀C不支持重載
Duplicate:http://stackoverflow.com/questions/479207/function-overloading-in-c – 2010-03-20 10:25:30
請參閱Leushenko 2014年答案使用C11 _泛型類型選擇器在愚蠢http://stackoverflow.com/questions/479207/function -overloading-在-C。 – 2015-04-16 07:52:21