c语言中外部变量的使用方法,C语言外部变量的使用以及erxtern的用法
網上有很多帖子問C語言中extern的用法,而且回答的詳細程度各盡不同. 所以我就像寫一篇博文來談談我對extern的看法,不一定十分恰當,只當大家共勉.
變量定義性聲明和引用性聲明
變量的聲明有兩種情況:
1、一種是需要建立存儲空間的。
例如:int a 在聲明的時候就已經建立了存儲空間。
2、另一種是不需要建立存儲空間的。
例如:extern int a 其中變量a是在別的文件中定義的。
前者是“定義性聲明(defining declaration)”或者稱為“定義(definition)”,而后者是“引用性聲明(referncing declaration)”或者簡成為“聲明(Declaration)”,從廣義的角度來講聲明中包含著定義,即定義是聲明的一個特例,所以并非所有的聲明都是定義
例如:int a; // 它既是聲明,同時又是定義。
然而對于 extern int a;// 來講它只是聲明不是定義。
extern int a = 10; // 定義一個變量,同時初始化為10,只是定義不再是聲明
注意: 由于C語言中定義變量的默認存儲類型是extern的
因此:
int a = 10; 等價于 extern int a = 10; // 只是定義不是聲明,但是extern int a = 10;作為定義在gcc下會有警告
一般的情況下我們常常這樣敘述,把建立空間的聲明稱之為“定義”,而把不需要建立存儲空間的聲明稱之為“聲明”。很明顯我們在這里指的聲明是范圍比較窄的,即狹義上的聲明,也就是說非定義性質的聲明
變量的聲明和定義與extern
在具體到extern的用法之前,有兩個概念必須要能分清楚:
聲明(Declaration)和定義(Definition)之間的區別.
聲明一個變量只是宣布這個變量的屬性,也就是說告訴編譯器這個變量時什么類型(如int, long, string 等).
而定義一個變量不僅是聲明了變量的屬性,同時也告訴編譯器給變量分配相應的存儲空間.
extern的用法詳解
在C語言中,修飾符extern用在變量或者函數的聲明前,用來說明“此變量/函數是在別處定義的,要在此處引用”。
extern修飾變量的聲明。
舉例來說,如果文件main.c需要引用extern.c中變量int value,就可以在main.c中聲明extern int value,然后就可以引用變量value。
這里需要注意的是,被引用的變量v的鏈接屬性必須是外鏈接(external)的,也就是說main.c要引用到value,不只是取決于在main.c中聲明extern int value,還取決于變量value本身是能夠被引用到的。這涉及到c語言的另外一個話題--變量的作用域。能夠被其他模塊以extern修飾符引用到的變量通常是全局變量。還有很重要的一點是,extern int value可以放在main.c中的任何地方,比如你可以在main.c中的函數fun定義的開頭處聲明extern int value,然后就可以引用到變量value了,只不過這樣只能在函數fun作用域中引用value罷了,這還是變量作用域的問題。對于這一點來說,很多人使用的時候都心存顧慮。好像extern聲明只能用于文件作用域似的。
總結起來可以這樣說,聲明只是告訴編譯器聲明的變量和函數是存在的,但并沒有真正分配空間給它,所以當后面的代碼用到前面聲明的變量或函數時,編譯器在編譯的時候不會報錯。鏈接的時候編譯器會去尋找這些變量和函數的內存地址,如果只聲明了但沒定義,鏈接器當然找不到它們了,所以就會報錯。而對它們進行定義了的話,編譯器就會給它們分配空間,它們就有自己的地址了,這時就能鏈接了。定義是要分配空間的,且定義只能有一次。而聲明不分配空間,可以聲明多次。
extern修飾函數聲明
從本質上來講,變量和函數沒有區別。函數名是指向函數二進制塊開頭處的指針。如果文件main.c需要引用extern.c中的函數,比如在extern.c中原型是int fun(int num),那么就可以在main.c中聲明extern int fun(int num),然后就能使用fun來做任何事情。就像變量的聲明一樣,extern int fun(int mu)可以放在main.c中任何地方,而不一定非要放在main.c的文件作用域的范圍中。
對其他模塊中函數的引用,最常用的方法是包含這些函數聲明的頭文件。
使用extern和包含頭文件來引用函數有什么區別呢?
extern的引用方式比包含頭文件要簡潔得多!extern的使用方法是直接了當的,想引用哪個函數就用extern聲明哪個函數。這大概是KISS原則的一種體現吧!這樣做的一個明顯的好處是,會加速程序的編譯(確切的說是預處理)的過程,節省時間。在大型C程序編譯過程中,這種差異是非常明顯的。
extern修飾符可用于指示C或者C++函數的調用規范
比如在C++中調用C庫函數,就需要在C++程序中用extern “C”聲明要引用的函數。這是給鏈接器用的,告訴鏈接器在鏈接的時候用C函數規范來鏈接。主要原因是C++和C程序編譯完成后在目標代碼中命名規則不同。
總結
關鍵字extern用來聲明一個變量(或函數),并指出它具有外部鏈接(它的名字在其它文件里是可見的)。被extern修飾的變量,其生存期為程序運行的整個過程(它在程序開始運行時被分配內存,在程序運行結束時才被收回)。被extern聲明的變量(或函數)將在同一文件的后續部分定義,或定義在其它的源文件中。
在C語言中,關鍵字extern用在變量或者函數的聲明前,用來說明“此變量/函數是在別處定義的,要在此處引用”。關鍵字extern用于變量的聲明:
示例
extern.c
/********************************************************** > File Name: extern.c > Author: GatieMe > Mail: gatieme@163.com > Created Time: 2015年03月27日 星期五 16時11分50秒 *********************************************************/
#include
#include
extern int ex_num = 20; // 作為變量定義會有警告
int num = 30;
int value;
char str[81] = "abcdefg";
main.c
/********************************************************** > File Name: main.c > Author: GatieMe > Mail: gatieme@163.com > Created Time: 2015年03月27日 星期五 16時12分14秒 *********************************************************/
#include
#include
extern int num; // 聲明一個外部變量,定義時使用int num = 30;
extern int ex_num; // 聲明一個外部變量,定義時2使用extern int ex_num = 20;
extern int value; // 聲明一個外部變量,定義時使用int value;
extern char str[81];
int a; // 既是聲明也是定義
extern int b; // 只是聲明不是定義
int c = 10; // 只是定義不是聲明
extern int d = 20; // 只是定義不是聲明, 但是作為變量定義會有警告
int main(void)
{
printf("num = %d\n", num);
printf("ex_num = %d\n", ex_num);
printf("value = %d\n", value);
printf("str = %s\n", str);
printf("a = %d\n", a);
// printf("%d\n", b); // ERROR, 鏈接錯誤,找不到變量定義
printf("c = %d\n", c);
printf("d = %d\n", d);
return EXIT_SUCCESS;
}
Makefile
#Makefile
main:extern.o main.o
gcc $^ -o $@
extern.o:extern.c
gcc -c $^ -o $@
main.o:main.c
gcc -c $^ -o $@
clean:
rm extern.o main.o
rm main
總結
以上是生活随笔為你收集整理的c语言中外部变量的使用方法,C语言外部变量的使用以及erxtern的用法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《狂飙》的编剧是懂“街霸”的,盘点剧中街
- 下一篇: 第五人格地窖怎么找(18183第五人格专