函數聲明

    本文將C語言的函數聲明在這裏做一總結。尤其注意同一工程中多個文件間函數調用和聲明的關係,很多C語言的教材上沒有涉及此話題。

 

1.目的:

    函數聲明的目的是告訴編譯器被調用函數的返回值類型、參數個數及參數類型,以便編譯器檢查函數調用語句的合法性。

 

2.語法:

    函數聲明的語法格式通常與函數定義的頭部是一致的,我們把函數定義的頭部拷貝下來,在後面加個分號就是函數聲明語句了。如果被調用函數是在另一個文件中定義的,可以在前面加一個extern,以表示是外部函數,也可以省略extern。

 

3.位置:

    函數聲明既可以放在某個函數的內部,也可以放在所有函數的外面。如果放在函數內部,則被聲明函數只能在該函數內部被調用。如果放在所有函數的外面,則聲明後面的所有函數都能調用被聲明函數。通常的做法是:將所有函數的聲明統一放在所有函數的最前面。

 

4.函數聲明可以省略的兩種情況:

    1) 被調用的函數定義在調用它的函數之前,這時被調用的函數可以不用聲明;

這是因爲編譯系統會先遇到被調用的函數定義,所以在調用之前已經知道該函數的返回值和參數類型。

 

    2) 函數的返回值和參數類型都爲整型。

這是因爲,當省略函數聲明時,編譯系統會默認被調用的函數的返回值類型和參數類型是整型。

注意: 有些書上說當函數的返回值爲整型時,可以省略函數聲明。這種說法是不恰當的,在Dev C++平臺下測試,不僅返回值要爲整型,參數也要爲整型時,纔可以省略函數聲明,否則編譯會報錯“conflicting types for function_name”。比如一個函數的頭部這樣定義:int fun(float p),在省略函數聲明的情況下,編譯系統先遇到對函數fun的調用時,已經默認fun的返回值類型和參數類型是整型,但是當遇到該函數的定義時,發現函數的參數類型並不是整型,因此認爲是“衝突的類型”。 

建議:對所有的函數都進行聲明,即使有時候可以省略。不要偷懶,這樣做比較安全。

 

5.多文件間的函數調用和聲明:

    在一個工程中,多個文件分別包含了一些函數的定義,如果一個文件內的函數要調用另一個文件內的函數,也需要進行函數聲明。不過,情況和單個文件有所不同。我在Dev C++平臺下進行了實驗,創建了一個“console application”類型的C工程,除了默認的main.c,還添加了兩個程序文件file1.c和file2.c。

    第一個實驗的代碼如下所示:

//file1.c 定義了一個函數fun1

float fun1(intp)

{

    return 3.11*p;  

}


//file2.c定義了一個函數fun2

float fun2(intp)

{

    return 3.22*p;

}


//main.c 調用函數fun1和fun2

#include“stdio.h”

int main()

{      

    float r1,r2;

    r1= fun1();  //錯誤的調用

    r2= fun2();  //錯誤的調用

    printf(" r1 = %f r2 =%f\n",r1,r2);

    return 0;

}

    第一個實驗我們沒有在main.c中對被調用函數fun1和fun2進行聲明,而且還寫了錯誤的函數調用語句(沒有傳遞參數)。對工程進行編譯,沒有報出任何錯誤,運行結果如下:


    這個結果顯然是看不懂的。

注意 :如果上面三個文件的內容在同一個文件中,編譯時會報錯。

 

    接下來 ,我們再做一個實驗:在main函數中增加對函數fun1和fun2的聲明,但是聲明是錯誤的,即和函數定義的頭部不一致。函數調用也是錯誤的,但是和聲明是一致的。修改後的main.c的定義如下:

//main.c 調用函數fun1和fun2

#include“stdio.h”

extern floatfun1();    //錯誤的聲明

externfloat fun2();    //錯誤的聲明

int main()

{      

     float r1,r2;

     r1= fun1();  //錯誤的調用

     r2= fun2();  //錯誤的調用

     printf("r1 = %f r2 = %f\n",r1,r2);

     return 0;

}

    同樣,編譯時沒有報出任何錯誤,運行結果如下:

 

    注意這個結果比較有意思,因爲沒有給fun1和fun2傳遞參數,函數省略了參數p,直接返回了3.11和3.22。

 

    最後一個實驗,在main函數中使用正確的函數聲明,但是進行錯誤的函數調用。修改後的main.c的定義如下:

//main.c 調用函數fun1和fun2

#include“stdio.h”

extern floatfun1(int);    //正確的聲明

externfloat fun2(int);    //正確的聲明

int main()

{      

     float r1,r2;

     r1= fun1();  //錯誤的調用

     r2= fun2();  //錯誤的調用

     printf("r1 = %f r2 = %f\n",r1,r2);

     return 0;

}

    這種情況下,編譯會報錯

 

    從以上的實驗中我們得出結論:同一工程中多個文件間存在函數調用時,應該進行函數聲明,並確保聲明是正確的。這樣就可以防止錯誤的函數調用和錯誤的運行結果。

發佈了40 篇原創文章 · 獲贊 119 · 訪問量 16萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章