| 上一篇 | 下一篇 |
|---|---|
| C 语言编译器的优化功能 |
1)volatile 关键字的作用是什么?
volatile:[adj] 易变的
C/C++ 编译器具有优化功能:在不改变程序逻辑的前提下,让生成的代码运行更快、体积更小或更省资源。
当开启优化时,处理器会把一些高频使用的变量的值放进缓存或寄存器中,这个时候它就不从内存中取了,虽然这可以提高效率,但当这个变量的值被修改了之后(比如被多线程或中断程序修改了),CPU 没有重新访问内存,就会造成数据不一致的问题。
解决方法就是使用 volatile 关键字。
volatile 是一个类型修饰符,用于告诉编译器,该变量的值可能会被改变(是不稳定的)。然后不论如何优化,编译器每次访问该变量时,都会直接从其内存地址中读取数据 (即:volatile 是让 CPU 直接去变量内存地址里去读取数据,而不是去缓存读取数据,用于防止编译器优化此变量 )。
使用:
c
volatile int flag = 1;
2)static 关键字的作用是什么?
static:[adj] 静态的
static 变量称为静态存储类型的变量,所谓静态就是变量在程序运行期间一直存在。
static 变量的特点如下:
- 在内存中以固定地址存放,而不是以堆栈方式存放(程序运行多次之后,依然存在同一地址);
- 只要程序没结束,此变量就不会消失,即使放在子函数中被反复调用,每次调用的时候,都会保留调用结束的值;
static修饰的全局变量,其他文件无法使用(其他文件即使使用extern声明,也无法访问该变量);- 如果没有初始化,那么静态变量的初始值默认是 0 。
举例,有如下程序:
c
#include <stdio.h>
void fun()
{
int a=10;
a++;
printf("%d %p\n",a,&a);
}
int main()
{
int i=0;
while(i<5)
{
fun();
i++;
}
return 0;
}
程序运行之后的结果为(运行两次):
c
/* 第一次运行结果 */
11 00000063867ff90c
11 00000063867ff90c
11 00000063867ff90c
11 00000063867ff90c
11 00000063867ff90c
/* 第二次运行结果 */
11 0000002554dff7dc
11 0000002554dff7dc
11 0000002554dff7dc
11 0000002554dff7dc
11 0000002554dff7dc
// 两次运行,分配的地址都是不确定的
现在将变量 a 定义为静态变量,并且不初始化:
c
#include <stdio.h>
void fun()
{
static int a;
a++;
printf("%d %p\n",a,&a);
}
int main()
{
int i=0;
while(i<5)
{
fun();
i++;
}
return 0;
}
程序运行之后的结果为(运行两次):
c
/* 第一次运行结果 */
1 00007ff74fb4a000
2 00007ff74fb4a000
3 00007ff74fb4a000
4 00007ff74fb4a000
5 00007ff74fb4a000
/* 第二次运行结果 */
1 00007ff74fb4a000
2 00007ff74fb4a000
3 00007ff74fb4a000
4 00007ff74fb4a000
5 00007ff74fb4a000
// 两次运行,分配的地址都是固定的,并且初始值为 0 (+1后才打印)
总结:
- 定义静态局部变量:延长生命周期,保持值不变
- 定义静态全局变量:限制作用域,别的文件不可调用
- 定义静态函数:限制函数作用域,别的文件不可调用
c
// 1. 静态局部变量
static int count = 0;
// 2. 静态全局变量
static int globalVar;
// 3. 静态函数
static void localFunc(void) {}