存储类&作用域&生命周期&链接属性

存储类

存储类,就是存储类型。用于描述变量空间开辟于内存中的什么地方。
存储类相关的关键字

  • auto
    修饰局部变量,表示这个局部变量为自动局部变量,分配在栈上(不初始化便值就是随机的),平时定义的局部变量就是定义auto的,只是省略了auto关键字而已。
  • static
    该关键字有两种用法,这两种用法之间没有任何联系,是完全独立的。
    static的第一种用法是,用来修饰局部变量,形成静态局部变量。
    static的第二种用法是,用来修饰全局变量,形成静态全局变量。

相同之处
静态局部变量在存储类方面(数据段)、生命周期方面和全局变量一样。
不同之处
作用域、链接属性不同。静态局部变量作用域是代码块作用域(和自动局部变量一样)、链接属性是无连接;全局变量作用域是文件作用域(和函数一样)、链接属性方面是外连接。

  • register
    该关键字被称为寄存器变量,和普通变量使用方式没什么区别,但寄存器变量的读写效率高很多。但寄存器数量有限,不保证一定放在寄存器中,慎用。
  • extern
    在编译C程序时,是以单个.c文件为单位的,编译时当b.c中用到a.c中定义的变量时,编译器会报错,这时我们可以使用extern关键字。extern修饰全局变量,就可以实现跨文件访问变量用。

定义与声明的区别
定义是编译器创建了具体变量,并为这个变量分配了内存。声明并没有分配内存,只是告诉编译器这个名字已经被分配内存了。
定义兼有声明的作用,定义本身就是声明。

  • volatile
    字面意思为可变的、易变的。使用volatile来修饰变量时,表示这个变量可以被编译器之外的东西改变。如在中断处理程序isr中、多线程中的别的线程以及硬件自动更改这个变量的值(编译器均无法预知)。此时应使用volatile告诉编译器这个变量属于这种情况。
    在需要处加volatile关键字而没有加的话,程序可能会被错误地优化。在不需要处加volatile关键字的话,程序虽然不会出错但会降低效率。

“编译器之内”
表示变量值的改变时代码作用的结果。
“编译器之外”
表示这个改变不是由代码造成的,编译器在编译当前代码时无法预知。

  • restrict
    该关键字由C99标准引入,被用于限定和约束指针。当使用restrict修饰指针时,它会告诉编译器,所有希望修改该指针指向的内存时,都必须使用该指针才可以进行,目的是为了让编译器能够进行更好的优化。

此关键字由C99所支持,可以利用“-std = c99”来开启GCC对C99的支持。

  • typedef
    该关键字归属为存储类关键字,但是实际上和存储类没关系。

作用域

局部变量的作用域时代码块作用域,可以访问的范围为定义该局部变量开始到代码块结束。
文件作用域是指全局的访问权限,函数和全局变量的作用域为.c文件中该函数或全局变量的定义位置开始到文件结束。

变量的掩蔽规则
如果两个同名变量作用域有交叠时,C语言规定作用域小的变量会掩蔽掉作用域大的变量。

如果想要在定义前访问时怎么办?声明

#include <stdio.h>

extern var;
int var = 10;

int main(){
	printf("hello world");
	return 0;
}

生命周期

  • 诞生:运行时在内存中分配变量空间。
  • 消亡:内存回收变量空间。

链接属性

程序的编译过程是:编译+链接
编译是为将函数/变量等编程.o二进制的机器码格式;链接是为了将各个独立分开的二进制的函数链接起来,形成一个整体的二进制可执行文件。

  • 外链接
    所需函数与变量可以在外部文件中找到,跨文件访问。extern修饰的全局变量和函数就是属于外链接的内容。
  • 内链接
    与外链接相反,所需的函数和变量在当前文件的内部就可以找到,static修饰的函数和全局变量,外部文件都将无法访问,只有文件内部才能访问。static修饰静态全局变量和函数都是内链接。
  • 无链接
    表示这个符号本身不参与链接,局部变量(auto、static) 都是无链接的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值