A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© chenhuan_ccit 中级黑马   /  2014-11-7 19:10  /  1574 人查看  /  4 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

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的作用在于限制该全局变量的作用域,只能在定义该全局变量的文件中才能使用,跟其他源文件中的同名变量互不干扰。

评分

参与人数 1技术分 +1 收起 理由
星河鹭起 + 1

查看全部评分

4 个回复

倒序浏览
来学习一下
回复 使用道具 举报
路过来学习一下。。
回复 使用道具 举报
点赞,学习一下
回复 使用道具 举报
路过学习一下
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马