2015-05-24 48 views
3

爲什麼下面的程序工作正常?瞭解C中的函數原型

int main() 
{ 
    int x; 
    x = foo(); 
    printf("%d",x); 
    getchar(); 
    return 0; 
} 

int foo() 
{ 
    return 2; 
} 

而不是這個程序?

//double function(void); 

int main(){ 
    double val; 
    val = function(); 
    printf("%ul\n",val); 
} 

double function(void){ 
    double num; 
    num = DBL_MAX; 
    printf("%ul\n",num); 
    return num; 
} 

在我的理解,在這兩種情況下的功能定義是main()之前缺席。那麼爲什麼在第一種情況下函數被調用,即使編譯器在main()之前沒有定義它,而不是在第二種情況下?

+0

注意,無論是舊的C標準(C99)和當前的C標準(C11)說,方案應生成診斷。只有古老的(C89/C90)標準允許第一個程序工作,而第二個程序總是失敗。如果你喜歡用破碎的代碼工作,那麼很好地寫入sloppier C89標準。寬鬆的規則是歷史的必然。如果沒有鬆懈,標準就不可能取得成功。但是舊的標準已經有15年了,你應該使用它,並且當你使用沒有原型的函數時,你的編譯器會發出警告。如果你的編譯器不行,可以找一個更好的編譯器。 –

+0

@JonathanLeffler,''ul'可用於'雙'嗎? –

+0

在'printf()'格式字符串中?沒有; '%ul'格式化一個'unsigned int',後跟一個字母'l',它不是轉換規範的一部分。如果你的意思是'%lu',那麼格式化一個'unsigned long'。當你在參數列表中傳遞一個'double'作爲相應的值時,它們都不會有用(或者甚至不可靠)。 –

回答

7

由於隱式函數聲明,編譯器假定未指定的類型默認爲int

在第一種情況下是巧合的,但不是在第二種情況下。

6

任何稱爲函數的東西C默認爲int類型,沒有參數(例如在第一種情況下)。如果編譯器找到符合的函數,則不會有錯誤。

在第二種情況下,編譯器編譯main()時認爲函數是int,但後來發現它不是真的,並報告錯誤!

評論:喬納森·萊弗勒說:

只有在C89/C90。不在C99中;不在C11中。當然,有些供應商仍然只實現C89的 ;一個值得注意的例子就是微軟!

+2

僅在C89/C90中。不在C99中;不在C11中。當然,有些廠商仍然只實現C89;一個值得注意的例子就是微軟! –

+0

這很有趣!我將它添加到回覆中(這些評論很容易在某個時候被刪除。 – jcoppens

1

在C中,如果定義了一個函數,那麼它的隱式返回類型是int

  • 在第一種情況的函數的返回類型爲int所以main()識別功能和沒有任何錯誤編譯。

  • 在第二種情況下,函數的返回類型爲double,因此main()未能識別函數,從而產生錯誤,因此您需要聲明函數的原型。如果返回類型沒有提到

此外,在老版本截止到C89則其被隱式視爲int

在C99標準中,即使返回類型爲int,也不允許返回類型被省略。

有關詳細信息,您可以檢查:implicit return type C

+0

@alk感謝編輯我的答案。 – aa1992