@Chita_
C语言 储存类别
- 变量的生命期和作用域
变量的生命期和作用域
变量具有生命期:从变量分配内存开始,到内存“取消分配”时结束
变量具有作用域:这些是程序中可见变量的部分
生命周期也称为存储持续时间
生命期
-
静态
一个静态变量是存在于整个程序执行期间;程序启动时即分配内存 -
自动
一个自动变量存在于包含它的块中。 执行进入块时分配的内存,执行离开块时取消分配的内存 -
动态
从分配内存到取消分配内存在动态变量。 分配和取消分配是通过动态内存分配函数调用显式完成的
作用域
- 局部变量
局部变量仅在当前最里面的块内部可见 - 全局变量
全局变量从声明行到文件末尾,在整个编译单元中都可以看到一个全局变量 - 外部变量
外部变量在所有编译单元中均可见
存储类一览
C语言储存类 | 声明 | 默认初始值 | 初始化频率 | 存储在 | 作用域 | 生命期 |
---|---|---|---|---|---|---|
自动 | 块内 | Garbage | 每次进入块 | 内存 | 局部 | 自动 |
静态 | 块内 | 0 | 程序第一次启动时 | 内存 | 局部 | 静态 |
块外 | 0 | 程序第一次启动时 | 内存 | 全局 | 静态 | |
外部 | 在所有块外 | 0 | 程序第一次启动时 | ,内存 | 外部 | 静态 |
寄存器 | 块内 | Garbage | 每次进入块 | Maybe in register | 局部 | 自动 |
自动储存类的声明
{
auto double x; /*Same as: double x;*/
int num; /*Same as: auto int num;*/
}
auto是定义在函数体或语句块内的变量的默认存储类
自动前缀是可选的;也就是说,任何局部声明的变量都是自动的,除非被定义为静态的
静态储存类的声明
{
static double local_static;
}
void func1(int a)
{
...
}
static int global_static;
void func2(int b)
{
...
}
必须包含静态前缀
例:
#include <stdio.h>
void strange( int x )
{
static int y;
if ( x == 0 )
printf( "%d\n", y );
else if ( x == 1 )
y = 100;
else if ( x == 2 )
y++;
}
int main (void)
{
strange(1); /* Set y in strange to 100 */
strange(0); /* Will display 100 */
strange(2); /* Increment y in strange */
strange(0); /* Will display 101 */
return 0;
}
输出
100
101
外部储存类的声明
外部储存类 是在任何函数主体外部定义的变量的默认存储类
void func1(int a)
{
…
}
int global;
void func2(int b)
{
…
}
例1:
#include <stdio.h>
float x = 1.5;
void show (void)
{
printf("%f\n", x); /* Access external x */
}
int main (void)
{
printf("%f\n", x); /* Access external */
show();
return 0;
}
例2a:
#include <stdio.h>
extern float x;
void show (void)
{
printf("%f\n", x); /* Access external x */
}
int main (void)
{
printf("%f\n", x); /* Access external x */
show();
return 0;
}
float x = 1.5;
例2b:
#include <stdio.h>
void show (void);
int main (void)
{
printf("%f\n", x); /* Access external x */
show();
return 0;
}
float x = 1.5;
#include <stdio.h>
extern float x;
void show (void)
{
printf("%f\n", x); /* Access external x */
}
寄存器储存类
最快的存储位于中央处理器本身的高速内存单元中,称为寄存器
程序员可以请求编译器使用CPU寄存器来存储
register int k;
编译器可以忽略请求,在这种情况下,存储类默认为auto
寄存器变量是包含它的块的局部变量
Variable Shadowing(变量阴影)
•声明内部范围内的变量并为其赋予与外部范围内声明的另一个变量相同的名称时,将发生变量阴影
int x = 100;
int main (void)
{
int x = 1;
printf("%d\n", x);
return 0;
}
外部作用域中的变量被内部作用域中的变量遮盖