extern 較深入的用法-全局-靜態

額外,說明

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 ();聲明。是一樣的。。 

待續。。。。。


          






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