今天,看着爲open()
手冊頁,我發現這個功能是「超載」:函數重載用C
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
我不認爲這是可能的C.有什麼「絕招」爲了實現這個?
以後編輯:
所以它不是真正的超載,採用可變參數的時候,因爲 - 你只能提供相同類型的多個參數。那麼,mode_t
幕後一個int?
今天,看着爲open()
手冊頁,我發現這個功能是「超載」:函數重載用C
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
我不認爲這是可能的C.有什麼「絕招」爲了實現這個?
以後編輯:
所以它不是真正的超載,採用可變參數的時候,因爲 - 你只能提供相同類型的多個參數。那麼,mode_t
幕後一個int?
它使用variable arguments名單。這些聲明只出現在手冊頁中,因爲這2個是你應該調用open()的唯一方法。實際的C函數將被聲明爲例如
int open(const char *pathname,int flags,...);
使用可變參數時,參數不需要是相同的類型。 printf
就是這個例子。
在open()的情況下,如果'flags
包含O_CREAT標誌,則第一個變量參數必須爲mode_t,因爲open()的實現需要它爲mode_t(後臺可能是unsigned int或unsigned長 - 但與可變參數無關)
您可以僞造它使用可變參數與...
int function(int x, ...);
「當O_CREAT在標誌中時,必須指定」模式,否則將被忽略。「
extern int open (__const char *__file, int __oflag, ...)
它採用varargs
如果__oflag
包含O_CREAT
只加載模式可變參數。
C確實可以用variable number of argument來編寫函數,例如printf
。這就是說,在C中沒有可靠的,跨平臺的方式來編寫一個只需要2或3個參數的函數;在一般情況下,你必須做類似
some_function(5, 6, 7, NULL);
some_function(5, 6, 8, 2, 5, NULL);
換句話說,你必須有一個終止的「sentinal」參數。另外,還可以包括以某種方式在前面的參數參數的個數,如
another_func(2, "hello", "world");
another_func(3, "goodbye", "cruel", "world");
的printf
系列函數採取這種方式;第一個格式參數包含所需的額外參數的數量;例如與printf("%f %f", 5.6, 7.11)
你知道必須有2個浮點參數。然而,這在用戶定義的庫函數中會有些不安全,因爲如果你說my_printf("%s %f %f %f %s", 5.6)
那麼你可能會發生段錯誤或更糟。幸運的是,大多數C編譯器會在編譯時檢查您的電話號碼爲printf
以避免此類問題。
在open
的情況下,該函數被聲明爲具有可變參數,並且僅在設置了O_CREAT
的情況下才檢查第三個參數。所以這就是它如何「安全」地確定是否存在第三個參數。我把「安全地」放在引號中,因爲從技術上講,在運行時沒有辦法知道在運行時實際傳遞了多少個參數。例如,下面的調用將編譯沒有任何錯誤或警告:
open("foo.txt", 5, "not an integer", 7); // extra and invalid parameters
open("bar.txt", O_CREAT); // third parameter is missing
如果'some_function()'需要'int's,則不應該用'NULL'結束它,因爲NULL在數值上下文中僅爲0。 'NULL'結束符與指針參數一起使用效果最佳。 – 2010-04-21 19:47:56
@Chris:好的,我通常使用NULL作爲終止符,而不管數據類型如何,但是你說得對,可能會讓人困惑,特別是對於不知道0和NULL是否相同的人,因爲他們可能會想他們可以寫'some_func(3,2,1,0,-1,NULL)',事實上這會導致0作爲終止參數。 – 2010-04-21 20:05:22
最近版本的gcc和glibc頭文件會一起爲您的最後兩個示例產生警告。 – caf 2010-04-21 23:22:08
mode_t確實是一個整數,但可以提供不同類型的參數,假設你知道如何解釋它們。 printf函數家族使用格式字符串來了解如何解釋其額外參數,即使它們的輸入方式不同。下面的答案有一些例子可以說明這一點。 – 2010-04-21 19:41:48
@Eli謝謝,我一定對Java感到困惑。 – 2010-04-21 19:47:07
像這樣的函數被稱爲可變參數函數。 – Chris 2012-01-22 19:22:55