您的位置:首页 > 编程语言 > C语言/C++

黑马程序员--C语言基础之--extern、static详解

2015-03-27 00:48 281 查看

------IOS培训期待与您交流! -------

一、函数中的extern和static

extern修饰的函数叫做外部函数,static修饰的函数叫做内部函数。

外部函数:在某个源文件中定义的函数允许其他源文件访问,就称为外部函数。完整的定义是要加上extern关键字,但默认是可以省略的。

内部函数:在某个源文件中定义的函数不允许其他源文件访问,就称为外部函数。内部函数用static修饰。

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;
}


2、static

从上面的例子可以看出,test.c中定义的test函数是可以被其他源文件访问的。

其实有时候,我们可能想定义一个"内部函数",也就是不想让其他文件访问本文件中定义的函数。这个非常简单,只需要在定义函数的时候加个static关键字即可。

如下所示

/*
test.c
*/
//内部函数的定义
static void test()
{
printf("调用了test函数");
}


此时,这个程序是可以编译成功的,因为我们在main函数前面声明了test函数(函数的声明和定义是两码事)。但是链接的时候,出现错误,test函数没有被定义。

这是因为test函数是test.c的内部函数,不允许其他文件访问,链接器找到不到test函数,就报错了。

3、总结

(1)、extern:在定义函数时,如果用extern修饰,则表示此函数是外部函数,能够被其他源文件访问。如果省略extern,默认也是外部函数。

如果当前源文件想要访问另一个源文件定义的外部函数,则需要在当前文件中用extern声明该外部函数,这里的extern也可以省略。

(2)、static:在定义函数时,在函数的最左边加上static可以把该函数声明为内部函数(又叫静态函数),这样该函数就只能在其定义所在的文件中使用。

static也可以用来声明一个内部函数。

二、变量中的extern和static

C语言中,一个变量只有先定义或者声明了,才能被后面的函数访问。

extern一般用来声明变量,也可以用来定义变量,如果用来定义变量,编译器会发出警告,所以最好不用extern定义变量。static只能用于定义变量。

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、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;
}


3、总结

(1)extern:可以用来声明一个全局变量,但是不能用来定义变量。

(2)默认情况下,一个全局变量是可以供多个源文件共享的,也就说,多个源文件中同名的全局变量都代表着同一个变量。

(3)如果在定义全局变量的时候加上static关键字,此时static的作用在于限制该全局变量的作用域,只能在定义该全局变量的文件中才能使用,

跟其他源文件中的同名变量互不干扰。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: