单片机/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) {}

相关推荐
牛油果子哥q9 小时前
多模态大模型工程入门:图文Embedding、图文RAG、图片解析、C++多模态接口封装实战
开发语言·c++·embedding
AIFQuant9 小时前
Python股票实时价格告警系统:WebSocket订阅与REST快照实战
开发语言·python·websocket·a股行情
wuyk55510 小时前
从零吃透 MQTT 通信|第 10 章 阿里云 / 腾讯云 MQTT 设备完整对接实战,三元组、签名、设备上云调试
c语言·开发语言·stm32·学习·阿里云·云计算·腾讯云
ocean210310 小时前
2025-2026年Java语言及生态面试高频知识点洞察
java·开发语言·面试
2302_11110 小时前
java时间类型
java·开发语言
小七在进步10 小时前
类和对象(三)
java·开发语言
夜不会漫长10 小时前
C++:类和对象(1)
java·开发语言·c++
czt_java10 小时前
Java文件IO核心知识点总结
java·开发语言
szarron10 小时前
HTOOL‑SA12 + HT06 近场探头组合实操|手持设备工位 EMI 预兼容排查完整流程
运维·服务器·开发语言·网络·射频工程·频谱仪