存储类关键字描述了不同关键字在存储系统功能中的功能以及区别。
①:auto 在C语言中只有一个作用,修饰局部变量,表示自动类型局部变量,分配在栈上。
②:static 在C语言中有两个使用方法(1)用于修饰局部变量=>静态局部变量。(2)用于修饰全局变量=>静态全局变量。静态局部变量与非静态局部变量在存储类型上有些不同,非静态局部变量分配在栈上(auto),静态局部变量变量分配在数据段(初始化为非0数据)和bss段(未初始化或初始化为0)
静态局部变量与全局变量的区别 (1)存储类型一样。(2)生命周期一样。(3)作用域与属性不同 静态局部变量为块作用域,全局变量为文件作用域(与函数一样)。静态局部变量无链接,全局变量为外链接。
使用static声明的变量反复定义无效,运行时只认第一次定义的值,并在其基础上进行累积,不会归位。
void fn(void)
{
static int n=10;
n+=50;
}
int main()
{
fn(); n:10->60
fn(); n:60->110
}
③:register 在C语言中只有一个作用,修饰的变量一般为全局变量(但在内核中有大量的局部register),编译器会尽量将此变量分配在寄存器中,分配在寄存器中变量调用会快很多。
④:extern 主要用于声明全局变量,使a.c中定义的变量可以在b.c中使用。C语言的编译器以文件为单位进行编译,在编译时不会去处理这个变量,在链接时才进行处理,声明时不能进行赋值。
⑤:volatile 可变的,异变的。C语言中用于修饰变量,表示可以被编译器之外的东西改变。如中断isr(中断引用变量)、多线程中的它线程(多线程共用变量)、硬件(硬件干预变量),造成的改变。编译器不会对volatile变量进行访问优化。对于中断而言容易出现一下情况:
a=3 无优化要读写3次
b=a 有优化要读1次写3次
c=b
中断出现以上这种情况容易发送隐性err,这种情况就可以将变量赋值为volatile。
⑥restrict C99中的新玩意,gcc支持的变量。只用于修饰指针,与编译器行为有关,表示某个值只会被当前指针修改。
int foo(int *x,int*y)
{
*x=0;
*y=1;
return *x;
}
极大情况下返回值为0,也可能直接中断等情况,编译器不会将返回值内容优化为0。
int foo(int *restrict x,int*restrict y)
{
*x=0;
*y=1;
return *x;
}
这种情况下,编译器会将返回值优化为0。
⑦typedef 是虽然划分为存储类关键字,但其实没啥关系。