黑马程序员技术交流社区
标题:
C语言的extern和static关键字
[打印本页]
作者:
chenhuan_ccit
时间:
2014-11-7 19:10
标题:
C语言的extern和static关键字
static和extern是C语言中重要的关键词,它们不仅可以用在变量上,还可以用在函数上。
1 函数与extern,static
这两个关键字用来修饰函数,extern修饰的函数叫做外部函数,static修饰的函数叫做内部函数。
外部函数:在某个源文件中定义的函数允许其他源文件访问,就称为外部函数。完整的定义是要加上extern关键字,但默认是可以省略的。
内部函数:在某个源文件中定义的函数不允许其他源文件访问,就称为外部函数。内部函数用static修饰。
1.1 extern
以下是两个源文件,main.c和test.c,test.c中定义了外部函数test(),main.c调用test()。
/*
test.c
*/
//外部函数的完整定义
extern void test()
{
printf("调用了test函数");
}
//默认情况下,函数都是外部函数,可以省略extern
void test1()
{
printf("调用了test1函数");
}
main.c想要访问test.c定义的外部函数,必须先声明该函数,不能#include test.c源文件,#include test.c將会把test.c的内容复制一份到main.c,这将导致test()函数的重复定义,链接时会报错。
/*
main.c
*/
//main.c中想要访问test()函数,得先声明该函数,应该使用extern关键字,表示引用其他源文件的外部函数
//当然,extern也可以省略
extern void test(); //声明test函数
int main()
{
test();
return 0;
}
1.2 static
从上面的例子可以看出,test.c中定义的test函数是可以被其他源文件访问的。其实有时候,我们可能想定义一个"内部函数",也就是不想让其他文件访问本文件中定义的函数。这个非常简单,只需要在定义函数的时候加个static关键字即可。如下所示
/*
test.c
*/
//内部函数的定义
static void test()
{
printf("调用了test函数");
}
此时,这个程序是可以编译成功的,因为我们在main函数前面声明了test函数(函数的声明和定义是两码事)。但是链接的时候,出现错误,test函数没有被定义。因为test函数是test.c的内部函数,不允许其他文件访问,链接器找到不到test函数,就报错了。
1.3 总结
1、extern:在定义函数时,如果用extern修饰,则表示此函数是外部函数,能够被其他源文件访问。如果省略extern,默认也是外部函数。如果当前源文件想要访问另一个源文件定义的外部函数,则需要在当前文件中用extern声明该外部函数,这里的extern也可以省略。
2、static:在定义函数时,在函数的最左边加上static可以把该函数声明为内部函数(又叫静态函数),这样该函数就只能在其定义所在的文件中使用。static也可以用来声明一个内部函数。
2 变量与extern,static
C语言中,一个变量只有先定义或者声明了,才能被后面的函数访问。extern一般用来声明变量,也可以用来定义变量,如果用来定义变量,编译器会发出警告,所以最好不用extern定义变量。static只能用于定义变量。
2.1 extern
在当前源文件定义了一个变量int a,可以用extern int a声明该变量。
int a ; //定义变量
int main()
{
extern int a; //声明该变量。当然,a是全局变量,在前面已经定义了,现在可以不用声明直接使用
printf("a=%d\n",a);
return 0;
}
int main()
{
extern int a; //此时必须声明该变量,否则报错,没有定义变量a
printf("a=%d\n",a);
return 0;
}
int a; //定义变量
在其他源文件定义了一个全局变量int a,当前源文件想要访问变量a,必须用extern int a声明该变量之后,才能使用该变量。
//test.c
int a ; //定义变量
//main.c
int main()
{
extern int a; //此时必须声明该变量,否则报错,没有定义变量a
printf("a=%d\n",a);
return 0;
}
在同一个源文件,能够重复定义相同的变量;它们实质上是一个变量。但是,不能多次定义初始化同一个变量。
int a; //重复定义变量a,并且都没有初始化
int a;
int b;
int b = 1; //重复定义变量b,只初始化一次
/*
int c = 1; //多次定义并且初始化,则会报错
int c = 2
*/
int main()
{
a = 1;
printf("a=%d\n",a);
return 0;
}
int a;
在不同的源文件,也能够重复定义相同的变量;它们实质上是一个变量。但是,不能多次定义初始化同一个变量。
//test.c
int a ;
int b = 1;
//int c = 1;
//main.c
int a; //重复定义变量a,没有初始化
int b; //重复定义变量b,但是只初始化一次
//int c = 1; //重复定义初始化变量c,报错
int main()
{
printf("a=%d\n",a);
return 0;
}
不能只声明变量,不定义变量。
//main.c
extern int a; //声明变量a
int main()
{
printf("a=%d\n",a); //没有变量a的定义,会报错
return 0;
}
//main.c
extern int a; //声明变量a
int main()
{
printf("a=%d\n",a); //会报错,因为在test.c,和main.c中找不到变量a的定义
return 0;
}
1.extern可以用来声明一个全局变量,但是不能用来定义变量。
2.默认情况下,一个全局变量是可以供多个源文件共享的,也就说,多个源文件中同名的全局变量都代表着同一个变量。
3.如果在定义全局变量的时候加上static关键字,此时static的作用在于限制该全局变量的作用域,只能在定义该全局变量的文件中才能使用,跟其他源文件中的同名变量互不干扰。
作者:
caozhichao
时间:
2014-11-8 00:17
来学习一下
作者:
易拉罐
时间:
2014-11-9 12:45
路过来学习一下。。
作者:
whbsspu
时间:
2014-11-10 08:47
点赞,学习一下
作者:
chri_liu
时间:
2014-11-10 08:49
路过学习一下
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2