1、如果沒有定義,只有聲明和調用:編譯時會報連接錯誤。undefined reference to `func_in_a'
2、如果沒有聲明,只有定義和調用:編譯時一般會報警告,極少數情況下不會報警告。但是最好加上聲明。
3、如果沒有調用,只有定義和聲明:編譯時一般會報警告(有一個函數沒有使用),有時不會報警告。這時候程序執行不會出錯,只是你白白的寫了幾個函數,而沒有使用浪費掉了而已。
實驗:在一個項目的兩個.c文件中,分別定義一個名字相同的函數,結果?
編譯報錯 multiple definition of `func_in_a'
結論:在一個程序中,不管是一個文件內,還是該程序的多個文件內,都不能出現函數名重復的情況,一旦重復,編譯器就會報錯。主要是因為編譯器不知道你調用該函數時到底調用的是哪個函數,編譯器在調用函數時是根據函數名來識別不同的函數的。
跨文件的變量引用
(1)通過實驗驗證得出結論:在a.c中定義的全局變量,在a.c中可以使用,在b.c中不可以直接使用,編譯時報錯 error: ‘g_a’ undeclared (first use in this function)
(2)想在b.c中使用a.c中定義的全局變量,有一個間接的使用方式。在a.c中寫一個函數,然后函數中使用a.c中定義的該全局變量,然后在b.c中先聲明函數,再使用函數。即可達到在b.c中間接引用a.c中變量的目的。
(3)想在b.c中直接引用a.c中定義的全局變量g_a,則必須在b.c中引用前先聲明g_a,如何聲明變量? extern int g_a;
extern關鍵字: extern int g_a; 這句話是一個全局變量g_a的聲明,這句話告訴編譯器,我在外部(程序中 不是本文件的另一個文件)某個地方定義了一個全局變量 int g_a,而且我現在要在這里引用它 告訴你編譯器一聲,不用報錯了。
問題:
1、我只在b.c中聲明變量,但是別的文件中根本就定義這個變量,會怎么樣? 答案是編譯報錯(連接錯誤)undefined reference to `g_b'
2、我在a.c中定義了全局變量g_a,但是b.c中沒有聲明g_a,引用該變量會怎么樣? 答案是直接抱錯了,未定義
3、在a.c中定義,在b.c中聲明,a.c和b.c中都沒有引用該變量,會怎么樣? 答案是不會出錯。只是白白的定義了一個變量沒用,浪費了
結論:不管是函數還是變量,都有定義、聲明、引用三要素。其中,定義是創造這個變量或者函數,聲明是向編譯器交代它的原型,引用是使用這個變量或函數。所以如果沒有定義只有聲明和引用,編譯時一定會報錯。undefined reference to `xxx'
在一個程序里面,一個函數可以定義一次,引用可以有無數次,聲明可以有無數次。因為函數定義或者變量的定義實際上是創造了這個函數/變量,所以只能有一次。(多次創造同名的變量會造成變量名重復,沖突;多次創造同名的函數也會造成函數名重名沖突)。聲明是告訴編譯器變量/函數的原型,在每個引用了這個全局變量/函數的文件之前都要聲明該變量/函數
局部變量能不能跨文件使用? 不能。因為局部變量屬於代碼塊作用域。他的作用域只有他定義的那個函數內部。
靜態局部變量能不能跨文件使用? 不能。因為本質上還是個局部變量。
討論跨文件使用問題,只用討論全局變量和函數就可以了。
原文:https://www.cnblogs.com/lanjianhappy/p/6035449.html