链接属性
标识符的链接属性决定如何处理在不同文件中出现的标识符
链接属性一共有三种:
- external 外部链接属性 -- 属于external的标识符不论声明多少次,位于几个源文件都表示同一个实体
- internal 内部链接属性 -- 属于internal的标识符在同一个源文件内的所有声明中都指向同一个实体,但位于不同源文件的多个生命则分属不同的实体
- none 无链接属性 -- 该标识符的多个声明被当做独立不同的实体
只要变量并非声明于代码块或函数定义内部,这个变量的链接属性默认为external
关键字static
和extern
可以修改链接属性。如果声明本身具有external链接属性,在前面加上static
可以使这个声明的链接属性变为internal, 这样可以防止变量被其他源文件调用
static
关键字支队默认链接属性为external的声明才有改变链接属性的效果(比如,对某一个代码块内部声明的变量加上static
并不会改变该变量的链接属性,改变的只是这个变量的存储类型,因为这个变量声明在函数内部,其默认链接属性不是external)extern
关键字用于源文件中某个标识符的第一次声明时,它指定该标识符具有external链接属性,但是如果用于该标识符的第二次或以后的声明时,它不会更改第一次声明所指定的链接属性, 例子:
static int i; //internal链接属性
int func() {
extern int i; //并没有更改上面的i的链接属性,这里声明的i会隐藏上面声明的i
}
存储类型
变量的存储类型由它的声明位置所决定
- 任何在代码块之外声明的变量总是存储于静态内存中,即不属于堆栈的内存,这类变量被称为静态变量,静态变量在程序运行之前创建,在程序的整个执行期间始终存在,它始终保持原先的值,除非给它赋值新的值或程序结束
静态变量如果不显示指定其初始值,静态变量将初始化为0
- 在代码块内部声明的变量存储于堆栈中,如果给一个位于代码块内部的变量加上
static
关键字,可以将这个变量改为静态变量 - 关键字
register
可以指示将代码块内部的变量的存储在机器的硬件寄存器而不是内存中,这类变量成为寄存器变量,一般来说,寄存器变量比存储在内存的变量访问效率要高,但这并不意味着可以将每个变量都声明为register,如果有太多register变量,编译器只会选取前几个实际存储于寄存器
static关键字总结
- static用于函数声明或者位于代码块之外的变量声明时, static用于修改链接属性,从external改为internal
- static用于代码块内部的变量时,sttaic用于修改变量的存储类型,将变量修改为静态变量,但不改变链接属性