【嵌入式C语言】关键字之类型修饰符
类型修饰符
- 类型修饰符-概念
- auto
- register
- static
- const
- extern
- volatile
类型修饰符-概念
类型修饰符:对内存资源存放位置的限定
auto
正常定义的变量,默认省略auto
如果是在{}之间定义的变量(局部变量),那就保存在栈里,是可读可写的。
{
auto char a; //保存在栈里
}
默认情况--------->就保存在栈里,是可读可写的
register
-
变量放在寄存器里,
限制变量定义在寄存器上的修饰符
,定义一些快速访问的变量 -
编译器会
尽量
的安排CPU的寄存器去存放这个A,如果寄存器不足时,a还是放在存储器中。这个关键字不是100%成功的。 -
& 这个符号对register不起作用,会报错
变量存储的地方
- 内存(存储器)
- 寄存器(越多越好,越多越快,CPU直接访问效率高)
打印看看main返回的地址是多少?
main也是可以返回一个地址的!
static
static - 静态的
- 局部静态变量(Local Static Variable)
当在一个函数内部声明一个局部静态变量时,它的生命周期持续整个程序运行期间
,而不是像普通局部变量那样仅在函数执行期间存在。这意味着每次调用该函数时,静态变量都会保留上次函数调用结束时的值。 - 全局静态变量(Global Static Variable)
全局静态变量的作用域仅限于声明它的文件内
,不能被其他文件访问。这有助于隐藏数据,防止其他部分的代码意外地修改它们。 - 静态函数(Static Functions)
该函数只能在声明它的文件中被调用,不能被其他文件访问。
const
常量的定义,只读的变量
const int a = 100;
还是可变的,不能显示的修改,可以用指针修改
- 内存泄露
extern
外部声明
volatile
告知编译器编译方法的关键字,不优化编译
修饰变量的值的修改,不仅仅可以通过软件,也可以通过其他方式(硬件外部的用户)
作用:告诉编译器该变量是容易发生变化的,不能对该变量进行优化,每次取值都必须从内存中取值而不是直接去取之前在寄存器中的值(确保本条指令不会被编译器的优化而忽略)
例子:
Volatile int a=20,b,c;
b=a;
C=a;
代码执行流程如下;
- B=a;先从a的内存中取值存放到寄存器,再把寄存器的值给存到b的内存
- C=a;把寄存器的值给存到b的内存
可以看出编译器对c=a这步进行优化,不再执行从a的内存中取值,而是直接从寄存器中取值,如果这段时间内a的发生变化,那么c就不能得到最新的值,这个时候就需要使用volatile告诉编译器,不要对变量a优化,每次都是从内存中取a的值
常见场景:
- 多线程使用共享变量:因为多线程是多核操作,同时进行
- 中断:中断程序会修改其他程序中使用的变量
- 硬件寄存器:因为寄存器随时会被修改,好比AD转换的寄存器,随时会因 为电压变化而修改
- 外部任务会修改变量
一个参数既可以是const还可以是volatile吗?解释为什么。
- 是的。一个例子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。
一个指针可以是volatile吗?解释为什么。
- 是的。尽管这并不很常见。一个例子是当一个中断服务子程序修改一个指向一个buffer的指针时。