单片机/C语言八股:(四)volatile 和 static 关键字的作用

上一篇 下一篇
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) {}

相关推荐
huaweichenai8 分钟前
php 根据每个类型的抽签范围实现抽签功能
开发语言·php
codeejun1 小时前
每日一Go-73、云原生成本优化 —— 资源限制 & 指标驱动扩容
开发语言·云原生·golang
就叫_这个吧2 小时前
Java注解、元注解、自定义注解定义及应用
java·开发语言·注解
Sam_Deep_Thinking2 小时前
聊聊Java中的of
java·开发语言·架构
小小de风呀5 小时前
de风——【从零开始学C++】(十一):list的基本使用和模拟实现
开发语言·c++·list
三行数学5 小时前
Matlab之父克利夫·莫勒尔逝世
开发语言·matlab
陌路205 小时前
C++高级进阶--夯实进阶基础(1)
开发语言·c++
梦想三三6 小时前
【PYthon词频统计与文本向量化】苏宁易购评论分析实战
开发语言·python
AI人工智能+电脑小能手6 小时前
【大白话说Java面试题 第93题】【Mysql篇】第23题:从查找速度来看,聚集索引和非聚集索引哪个更快?
java·开发语言·数据库·mysql·面试
zlinear数据采集卡6 小时前
基准电压电路深度解析:从理论参数到ZLinear采集卡的精准参考实战
c语言·单片机·嵌入式硬件·fpga开发·自动化