黑马程序员_C语言的extern和static关键字

iOS,Android,Java培训,期待与您的交流
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;
}
2.2    static
static定义的全局变量不能被其他源文件访问,只能被当前源文件访问。
//test.c
static int a;  //静态全局变量,只能在本文件访问
void test()
{
    a = 10;
}  

//main.c
extern int a;  //声明变量a
int main()
{
    printf("a=%d\n",a);   //会报错,因为在test.c,和main.c中找不到变量a的定义
    return 0;
}
2.3    总结
1.extern可以用来声明一个全局变量,但是不能用来定义变量。
2.默认情况下,一个全局变量是可以供多个源文件共享的,也就说,多个源文件中同名的全局变量都代表着同一个变量。
3.如果在定义全局变量的时候加上static关键字,此时static的作用在于限制该全局变量的作用域,只能在定义该全局变量的文件中才能使用,跟其他源文件中的同名变量互不干扰。
iOS,Android,Java培训,期待与您的交流
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值