1. 程式人生 > >C中extern的使用方法體會

C中extern的使用方法體會

extern的作用:拋開extern "c"這種特殊用法,它的作用簡單來說就是改變了一個符號的作用域,這個符號可以是變數,可以是函式。一個全域性變數原本他的作用域只在一個C檔案內部,通過extern就可以讓其擴大到整個工程。

一個實際的例子:
a_test.c

#include <stdio.h>
extern void fun();//引用外部函式
int a = 10;//定義一個全域性變數
void main()
{
	fun();
	a ++;
	fun();
	return;
}

b_test.c

#include <stdio.h>
extern int a;
void fun()
{
	int b = a;
	printf("b: %d\n", b);
}

可以看到全域性變數a和函式fun分別在b_test.o和a_test.o中是未定義符號,他們都來自外部,需要在連線的時候才會找到定義。
在這裡插入圖片描述
執行結果:
b: 10
b: 11

仔細分析這種寫法,為了引用外部函式,無論從是程式碼的可讀性,擴充套件性各種角度來看,顯然使用更常見的標頭檔案寫法會更好,全域性變數也是如此。所以改成下面這種寫法。

b_test.c

#include <stdio.h>
#include "a.h"//將全域性變數的extern封裝到標頭檔案中
void fun()
{
	int b = a;
	printf("b: %d\n", b);
}

a.h

extern int a;

上面這種寫法在後續有其他.c需要使用這個全域性變數的時候,都可以很方便的引用到,而不需要每個.c都extern。或者有新增的需要外部引用的全域性變數,也只需要在標頭檔案中不斷新增即可。

另外還有一點,不要出現extern int a =3;這類的寫法,如果帶賦值的話,那就是定義而不是簡單的聲明瞭。可以看到用nm a對應的符號是D而不是U
在這裡插入圖片描述
這個時候再連線就會出現符號重定義了。就算這個寫法用在原始定義上,這個例子中就是在a.c中寫成extern int a = 10;其作用上也不會有任何差別。總而言之,extern 同時定義的寫法毫無意義~~

最近公司發起排查,堅決除掉在.c中出現extern 外部符號的情況。這種問題的產生往往都是本領域要引用其他領域的全域性變數,但是那個領域又沒有提供相應的標頭檔案,就會出現有人偷懶直接在.c中extern的情況。為了長遠的發展角度,還是要勤快些呀。