C語言關鍵字之extern

extern譯爲“外面的,外部的”,在C語言中用來聲明一個變量爲外部變量,也叫全局變量;或者聲明一個函數在外部進行了定義。也就是說,用extern修飾的變量或函數在同一工程下的其他文件也可以進行調用。

下面用具體的例子說明extern的用法。

1.extern對變量的聲明

假設在test.c文件中定義了一個變量a,如果在mian.c文件中想調用它,那麼有三種方式:①將變量a在test.h頭文件中聲明爲全局變量;②在main.c文件中調用變量a之前將a聲明爲全局變量;③變量a在test.c定義時直接聲明爲全局變量。

1.1在頭文件中聲明爲全局變量

test.h

#ifndef __TEST_H__
#define __TEST_H__

extern a;//聲明變量在外部進行了定義

#endif

test.c

#include <stdio.h>
#include "test.h"

int a=10;//定義變量,並進行賦值

mian.c

#include <stdio.h>
#include "test.h"//一定要包含頭文件纔可以使用全局變量a

int main()
{
    printf("a=%d \r\n",a);//在test.c中定義過,並賦值爲10,此處應該輸出10
    a=20;
    printf("a=%d \r\n",a);//重新賦值,應該輸出20
}

輸出結果:

1.2在main.c文件中調用變量a之前將a聲明爲全局變量

test.c

#include <stdio.h>
//#include "test.h"//將.h文件屏蔽掉

int a=10;//定義變量,並進行賦值

mian.c

#include <stdio.h>
//#include "test.h"//屏蔽掉頭文件

extern int a;//聲明外部變量

int main()
{
    printf("a=%d \r\n",a);//在test.c中定義過,並賦值爲10,此處應該輸出10
    a=20;
    printf("a=%d \r\n",a);//重新賦值,應該輸出20
}

輸出結果:

兩種方法從結果看都對,事實上,兩種方法本質是一樣的,第一種main.c包含了test.h頭文件,而test.h頭文件中進行了外部聲明,也就相當於間接在main.c中進行了外部聲明;第二種直接在main.c中進行了聲明。

1.3定義時直接聲明爲全局變量

test.c

#include <stdio.h>
//#include "test.h"//將.h文件屏蔽掉

extern int a=10;//定義變量,並進行賦值,並聲明爲全局變量

mian.c

#include <stdio.h>
//#include "test.h"//屏蔽掉頭文件
//extern int a;//屏蔽掉,不做外部聲明

int main()
{
    printf("a=%d \r\n",a);//在test.c中定義過,並賦值爲10,此處應該輸出10
    a=20;
    printf("a=%d \r\n",a);//重新賦值,應該輸出20
}

輸出結果:

以上三種方式都可以正確定義聲明一個全局變量。但是注意,①像第3中方法這種定義時直接聲明的情況只能用在.c文件中,不能用在.h頭文件中,否則編譯會報錯;②不可以只在.h頭文件聲明外部變量,而在外部.c文件中不對變量進行定義,這樣也會報錯;③不可以在.h頭文件中進行定義變量,.h頭文件只能進行聲明。

2.extern對函數的聲明

假設在test.c文件中定義了一個求和函數sum(int a,int b),如果在mian.c文件中想調用它,那麼有兩種方式:①將求和函數sum(int a,int b)在test.h頭文件中聲明爲全局變量;②在main.c文件中調用求和函數sum(int a,int b)之前將求和函數sum(int a,int b)聲明爲全局變量;③求和函數sum(int a,int b)在test.c定義時直接聲明爲全局變量。

2.1在頭文件中聲明爲全局函數

test.h

#ifndef __TEST_H__
#define __TEST_H__

extern int sum(int a,int b);//聲明函數在外部進行了定義

#endif

test.c

#include <stdio.h>
#include "test.h"

int sum(int a,int b)//求和函數,返回a+b之和
{
    return a+b;
}

mian.c

#include <stdio.h>
#include "test.h"//加載頭文件

int main()
{
    int c;
    c=sum(10,20);//求和
    printf("c=%d \r\n",c);//應該輸出30
}

輸出結果:

事實上,在.h文件中聲明函數時,不用加extern也行,只要調用此函數的.c文件包含test.h頭文件即可。

2.2在.c文件中調用之前將函數聲明爲全局函數

test.c

#include <stdio.h>
//#include "test.h"//將.h文件屏蔽掉

int sum(int a,int b)
{
    return a+b;
}

main.c

#include <stdio.h>
//#include "test.h"//屏蔽掉頭文件

extern int sum(int a,int b);//在調用之前聲明外部函數

int main()
{
    int c;
    c=sum(10,20);//求和
    printf("c=%d \r\n",c);//應該輸出30
}

輸出結果:

2.3定義時直接聲明爲全局變量

test.c

#include <stdio.h>
//#include "test.h"//將.h文件屏蔽掉

extern int sum(int a,int b)//直接聲明爲外部函數
{
    return a+b;
}

mian.c

#include <stdio.h>
//#include "test.h"//屏蔽掉頭文件

int main()
{
    int c;
    c=sum(10,20);//求和
    printf("c=%d \r\n",c);//應該輸出30
}

輸出結果:

以上三種方法可以正確聲明定義一個外部函數。事實上,我在使用VS2010編譯時,在test.c文件中對求和函數不用extern進行外部聲明,在test.h文件中也不做聲明,也是可以編譯運行成功的,但是會出現警告,如下圖:

總結:

爲了避免可能的錯誤,大家還是規範些代碼比較好。一般對於全局變量和函數採用1.1和2.1的方式,這樣代碼層次清晰,方便理解和調試

歡迎大家在評論區討論。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章