額外,說明
0,定義 相當於 聲明+分配內存;
聲明 就是 聲明;
只要在文件裏 聲明 了 某個變量,, 就可以確保 ‘編譯’ 能通過,若其他文件裏有 定義,則也可以確保 ‘鏈接’ 可以通過,,,否則 鏈接 不過。。。
1、同一變量名,全局的和靜態的可同時存在於不同的.c文件裏。
如,int a = 1; 在 global.c 裏;
static int a = 2; 在 static.c裏; gcc -o main.o static.c global.c 可編譯通過。
除在static.c文件裏引用a的值爲2之外,其他地方的文件引用a都是1(global)
2、int a=0; global.c
int a; global22.c
也可以編譯通過(只能有一個初始化), 因爲 他把第二個默認成聲明,可鏈接 到第一個a;
3、在不同的C文件中可以,以static形式來聲明同名全局變量;
如 static int a=1; global.c (在該文件內引用時 a 是1)
static int a=3; global22.c (在該文件內引用時 a 是3)
注意:若只有這兩個a,沒有 全局的a, 則在第三個文件中聲明a時,鏈接會出 現錯誤,因爲不知道應該鏈接到哪個文件裏的a。
4, 當然,同一文件裏,不能同時出現, int a = 1; static int a = 2;的;
5,同一文件裏,全局變量和局部變量是可以同名存在的,強龍不壓地頭蛇,
如,局部變量(可以是靜態局部變量)定義在 函數裏,與全局同名。
5、static局部變量和普通局部變量有什麼區別:static局部變量只被初始化一次,下一 次依據上一次結果值。
6、程序的局部變量存於棧中,全局變量存於靜態區中,動態申請數據存在於堆中。
原鏈接 http://bbs.csdn.net/topics/310185558
extern較奇怪的問題,摘抄部分分析,留作備份,,正常用法附在最下邊。。
// a.c
int i; // 0000000000000004 C i
// b.c
int i = 10; // 0000000000000000 D i
用gcc -o test a.c b.c 可以編譯通過。
如果改爲
// a.c
int i = 10;
// b.c
int i = 10;
則編譯不過。。。那就會出現重複定義的錯誤了。。
下面是牛逼人士的分析:
用nm可以幫助理解三種不同的形式的變量說明:
int x; /* C (Common) 聲明(可能同時也定義)變量, 到了鏈接階段, */
/* 1. 如果沒在其他模塊發現同名(D)符號,作爲未初始化的全局變量, 放在BSS */
/* 2. 如果有在其他模塊發現同名(D)符號,作爲已初始化的全局變量, 放在數據段 */
int y = 1; /* D (Data) 定義變量,作爲已初始化的全局變量, 放在數據段 */
extern int z; /* U (Undefined), 聲明變量, 到了鏈接階段 */
/* 1. 如果在其他模塊有且僅有一個類型(D)的同名符號,將此符號解析到此 */
/* (D)符號,作爲已初始化的全局變量, 放在數據段 */
/* 2. 如果在其他模塊有兩個或更多的類型(D)的同名符號,*/
/* 報告“重複定義”,鏈接失敗 */
/* 3. 如果在其他模塊未發現類型(D)的同名符號,但是至少有一個類型(C) */
/* 的同名符號, 將此符號解析到此(C)符號上,
/* 作爲未初始化的全局變量, 放在BSS */
簡單來說,
int x; 可以在多個模塊,
int x = 1; 只能在一個模塊
extern int x; 可以在多個模塊, 且至少還需要在其他模塊有一個 int x; 或 int x = 1;
》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》
以下是我的通俗理解,功能:《“引用前聲明”》
一、extern 作用於變量:
就是a.c 和b.c一塊gcc -o成一個test 的ELF,,a.c中定義了一個全局變量,,,現在你想在b.c裏邊用它,
呢麼你就要在b.c裏把該變量extern一下,然後就能用了。當然,一般包含在b.c 上邊include的頭文件裏邊。
所以,也就有了,只能有一處定義,可以在多處“引用前聲明”。。
我(某.c)要是extern 了一個變量,,
一、我不一定用它。。二、我如果用了,我就是用extern來說明一下,我沒有定義它,
在別處定義它,先讓我編譯過去,鏈接的時候再說。。。
另外,一、一個全局變量默認就是extern的,如:
int i = 5;//與extern i= 5;是一樣的,
即(extern)int i = 5; //extern 省略了
int i //定義全局變量
int i= 5;//定義並初始化全局變量
extern int i;// 聲明全局變量i
<pre name="code" class="html" style="color: rgb(51, 51, 51); font-size: 14px; line-height: 24px; ">extern int i= 5;//定義並初始化全局變量
//二和四是一樣的。二省了而已。。。
二、extern 作用於函數。
與作用於變量很類似,默認int func(){}; 就是extern int func(){},
呢麼別的 *.c 文件不需要做什麼就可以用這個函數了。還是呢句話,我沒有定義實現這個函數,
但我聲明一下,它在別的文件裏定義實現了,,你先讓我編譯過,鏈接的時候我再給你說它在哪個文件裏定義的
鏈接的時候我沒有明確告訴你,你再給我報鏈接出錯!!
另外: extern int func()聲明;與 int func ();聲明。是一樣的。。
待續。。。。。