C语言中标识符的链接属性和static关键字
一、链接属性
C语言中标识符(变量、函数等)的链接属性共有三种:external(外部)、internal(内部)和none(无)。
none:该标识符是单独的个体,其多个声明都是独立的不同的实体;
internal:该标识符在同一个源文件内的声明都指同一个实体,但位于不同源文件的多个声明则分属不同的实体;
external:该标识符不论声明多少次、位于几个源文件都表示同一个实体。
通常声明在代码块之外的标识符默认链接属性为external,在代码块内的为none。
extern和static关键字可以修改标识符的链接属性。如果某个声明正常情况下具有external链接属性,在它前面加上static关键字,可以将其链接属性修改为internal。注意:static只对缺省链接属性为external的声明才有改变链接属性的效果。为某个标识符指定external链接属性,这样就可以访问在其他任何位置定义的这个实体,当然extern和static关键字只有在声明中才是必须的,当用于具有文件作用域的声明时,这个关键字是可选的,如:
1.cpp
#include <stdio.h>
int value1 = 12;
void func1()
{
//...
}
main.cpp
#include <stdio.h>
#include "1.cpp"
int main()
{
//extern int value1; //可省略
//int value; //不加extern关键字则与1.cpp中的value1不是同一个实体
printf("value1=%d\n", value1);
return 0;
}
当extern关键字用于源文件中一个关键字的第1次声明时,它指定该标识符具有external链接属性。但是,如果它用于该标识符的第2次或以后的声明时,并不会更改由第一次声明所指定的链接属性。
二、static关键字
当用于不同的上下文环境时,static关键字具有不同的意思。
1、用于函数定义或者代码块之外的变量声明时:
static用于修改标识符的链接属性,从external改为internal,但标识符的存储类型和作用域不受影响。
凡是在代码块之外声明的变量总是存储在静态内存中。
①用static修饰的函数,其链接属性为internal,因此只能被当前源文件中的其他函数调用,而不能被该源文件之外的其它源文件调用,通常用于声明一个只在当前源文件使用的函数,好处是:可以在其它源文件中定义相同名字的函数而不会引起冲突。
②static修饰的代码块外的变量,将其链接属性从external修改为了internal,即该变量只能在该源文件中使用;此外,该变量仍然存储在静态内存中,其在程序运行前创建,在程序的整个执行期间始终存在(跟链接属性无关)。
2、用于代码块内部的变量声明时:
static用于修改变量的存储类型,从自动变量(auto)修改为静态变量(static),变量的链接属(默认为none)性和作用域不受影响。
静态变量在程序运行前创建,在程序的整个执行期间始终存在。
总结:
1、代码块外声明的标识符
1)链接属性默认为external;2)存储类型为静态;3)可以将链接属性改为static。
2、代码块内的声明
1)链接属性默认为none;2)存储类型为自动;3)链接属性不可改为static,可改为external;4)用static声明时是将其存储类型声明为静态存储;
3、在静态变量的初始化中,可以把可执行程序文件想要初始化的值放在当前程序执行时变量将会使用的位置,当可执行程序载入内存时,这个已经保存了正确初始值的位置将赋值给那个变量。如果不显式指定其初始值,静态变量将初始化为0。