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的方式,这样代码层次清晰,方便理解和调试。
欢迎大家在评论区讨论。