详解static与extern的区别

我们必须知道:

C/C++声明的变量默认是内部链接,函数默认是外部链接。

关键字extern和static用于在声明中,修改标识符的链接属性(链接类型表明了一个标识符的可见性)。

这里主要就是比较两者对于标识符在链接属性方面的影响。


static只讨论其对变量或函数实体链接属性的影响)

1,如果某个声明在正常情况下具有external链接属性,在它前面加上static关键字可以使他的链接属性变为internal

例如:

int main()
{
    int a;//a具有默认的external链接属性
    return 0;
}
我们将变量a的声明前面加上static

static int a;//static改变a的链接属性
那么变量a就将被这个文件所私有,在其他源文件中,如果也链接到一个叫做a的变量,那么它所引用的是另一个不同的变量。


2,类似的,也可以把函数声明为static

static int fun();
将函数fun由默认是外部链接,改为内部链接,这样可以防止该函数被其他源文件调用。


,3,值得注意的是:static只对缺省链接属性为external的声明才有改变链接属性的效果。

例如:在函数fun()中

fun()
{
	int b = 0;
}
b在函数体内,作用域就是函数内,只在函数体内有效,其链接属性为internal,不为external。

所以加不加static对于其链接属性没有什么影响。(当然,会影响b的存储类型和生命周期。)


extern

1,extern可置于变量或者函数前,以表示变量或者函数的定义在别的文件中,提示编译器遇到此变量或函数时,在其它模块中寻找其定义。

例如:

void fun()
{
	char a = 10;//a的链接属性为internal
	extern int b;//通过关键字extern,指定b的链接属性为external
}

将b指定为extern链接属性,这样,函数就可以访问在别的源文件中的外部变量了。


2,对于extern变量来说,仅仅是一个变量的声明,其并不是定义,不会分配内存空间。

因为,对某一变量或函数的指定extern链接属性,都是建立在外部已有该实体的情况下,不然链接时会无法找到该实体。

通过使用extern关键字声明变量名而不定义它。

int a;//a是一个定义
extern int b;//b是一个声明

如果给某一变量初始化,则不管有无extern,都视为定义。

extern int c = 10;//c是一个定义


3,在C++中extern还有另外一种作用,用于指示C或者C++函数的调用规范。
比如在C++中调用C库函数,就需要在C++程序中用extern“C”声明要引用的函数。这是给链接器用的,告诉链接器在链接的时候用C函数规范来链接。主要原因是C++和C程序编译完成后在目标代码中命名规则不同,用此来解决名字匹配的问题。

示例:

(1)仅对一个类型、函数、变量或常量指定链接规范

extern “C” void Fun1();//指定某一个函数的链接规范
extern "C" const constnumber;//定义常量
extern "C" struct Student{...};//指定一结构体变量
(2)对一段代码指定链接规范,将其包含在extern "C" {}中。

#ifdef __cplusplus
extern "C" {
#endif
//放入一段代码

#ifdef __cplusplus
}
#endif


总结

综上详细分析,static与extern,我们主要讨论的是他俩在对标识符的链接属性影响上的不同。抓住关键点,就抓住了一把利器,可以破开一些迷雾,让我们思路更清晰。

你可能感兴趣的:(C知识点,C++知识点)