将平时学习的做个记录。
首先介绍作用域的概念:
作用域
代码块作用域:在代码块中定义的变量具有代码块作用域。
函数原型作用域:适用于函数原型中使用的变量名。函数原型作用域从变量定义处一直到原型声明的末尾。
int mighty(int moust, double large);
文件作用域:在所有函数之外定义的变量具有文件作用域。具有文件作用域的变量从它定义处到包含该定义结尾处都是可见的。
链接
外部链接:具有外部链接的变量可以在一个多文件程序的任何地方使用。
内部链接:具有内部链接的变量可以在一个文件的任何地方使用。
空链接:具有代码块作用域或者函数原型作用域的变量具有空链接。
具有文件作用域的变量可能是内部链接或者外部链接。通过是否使用static判断。
int giants = 5; //文件作用域,外部链接
static int dodgers = 3; //文件作用域,内部链接
int main()
{
....
}
存储时期
静态存储时期:如果一个变量具有静态存储时期,它在程序执行期间将一直存在。
具有文件作用域的变量具有静态存储时期。
对于具有文件作用域的变量,关键词 static 表明链接类型。
自动存储时期:具有代码块作用域的变量。在程序进入定义这些变量的代码块时,将为这些变量分配内存;当退出这个代码块时,分配的内存将被释放。
存储类 | 时期 | 声明方式 |
---|---|---|
自动 | 自动 | 代码块内 |
寄存器 | 自动 | 代码块内,使用关键字register |
具有外部链接的静态 | 静态 | 所有函数之外 |
具有内部链接的静态 | 静态 | 所有函数之外,使用关键字static |
空链接的静态 | 静态 | 代码块内,使用关键字static |
使用register声明寄存器变量。
寄存器变量时存放在一个寄存器而不是内存中,所以无法获得寄存器变量的地址。
声明寄存器变量仅仅只是一个请求,编译器必须在请求与可用寄存器的个数或可用高速内存的数量之间做平衡,所以不一定会成为寄存器变量,然而,依然不能对它使用地址运算符。
静态变量
- 具有文件作用域的变量自动具有静态存储时期
具有代码块作用域的静态变量,需要用 static 声明。
从一次函数调用到下一次调用,计算机都记录着它们的值。
静态变量和外部变量在程序调入内存时已经就位了。
2. 具有外部链接的静态变量
这类变量具有文件作用域,外部链接和静态存储时期。
把变量的定义声明放在所有函数之外,即创建了一个外部变量。
为了使程序更加清晰,可以在使用外部变量的函数中通过使用 extern 关键字来再次声明它。如果变量在别的文件中定义,使用 extern 就是必须的。
int tern = 1;
main()
{
extern int tern;
}
第一次声明称为定义声明,第二次声明称为引用声明。关键字extern表明该声明不是一个定义,因为它指示编译器参考其他地方。
不要用extern来进行外部定义,只用它来引用一个已经存在的外部定义。一个外部变量只可进行一次初始化,而且一定是在变量被定义时进行。
3. 具有内部链接的静态变量
这类变量具有静态存储时期,文件作用域,内部链接。
通过使用static在所在函数外部进行定义。
static int svil = 1;
int main()
{
}
普通的外部变量可以被程序的任意文件中所包含的函数使用,而具有内部链接的静态变量只可以被与它在同一个文件中的函数使用。