1、extern:声明一个外部变量或函数
对于单个.c源文件来说:
extern 主要改变变量或函数的作用域,或链接外部定义的变量或函数
#include <stdio.h>
void test()
{
extern int a;
if(1)
{
printf("a =%d\n",a);
}
return ;
}
int a=100;
int main()
{
test();
}
/*
没有extern声明时,全局变量a的作用域没有涉及到test函数,在test中使用就会报错。
使用了extern时,a=100;即扩展了a的作用域到extern int a----->test()函数结束
表明一点:扩展作用域;
*/
在函数中多次使用extern int a:
#include <stdio.h>
void test()
{
extern int a;
a=99;
if(1)
{
extern int a;
int b =a;
printf("b =%d\n",b);
}
return ;
}
int a=100;
int main()
{
test();
printf("main b = %d\n",a);
}
/*
b=99,a作为全局变量的作用域被扩展到了函数test中,a=99修改全局变量a的值;
所以main b = 99;
即:注意作用域和变量是否被修改。
*/
对于外部定义的文件来说:
链接外部的变量或函数,给本文件使用,在本文件修改了值,其它文件引用改变的值已经发生了变化
//------a.c
#include <stdio.h>
extern int a;
int test1()
{
//printf("_%s_\n",__FUNC__);
printf("a= %d",a);
return 0;
}
int main()
{
test1();
}
/*
a被声明为外部变量,如果使用:gcc -c a.c 生成a.o不会报错,
但连接为可执行文件时报没有定义的错,
即使用:gcc a.c,连接时需要去找a的定义,发现找不到使用a就没有定义。
*/
在b.c中定义全局变量:int a=100;
使用gcc a.c b.c -o a.out ==>编译通过并运行成功
2、编译和连接问题
extern 就实现了两个功能:【在源文件中扩展变量的作用域】【实现变量的跨文件访问】
编译时,编译器会从使用extern进行外部变量声明的地方开始在文件中查找外部变量的定义,如果找到了定义,则该变量的作用域在该文件中被扩展。否则报 no defined error!
-c生成目标文件,其作用也是在进行了预处理之后进行的操作,因为在连接时区寻找extern变量的定义,所以不会报错。
3、注意
extern int a;【可以不指名变量类型,即:extern a】还是指名好一目了然。
extern int a;作为全局变量声明时,不要再初始化,编译器报重复定义或初始化错
extern int a;在函数中使用注意该变量的 作用域
static int i=10; //-------1
int fun()
{
int j;
extern int k; //------2
extern int i; //------3
}
/*
1和3的i是同一个。extern int i去找的是本文件中的i;
*/