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

相关推荐
紫金修道13 小时前
【DeepAgent】概述
开发语言·数据库·python
Via_Neo13 小时前
JAVA中以2为底的对数表示方式
java·开发语言
书到用时方恨少!13 小时前
Python multiprocessing 使用指南:突破 GIL 束缚的并行计算利器
开发语言·python·并行·多进程
cch891814 小时前
PHP五大后台框架横向对比
开发语言·php
天真萌泪14 小时前
JS逆向自用
开发语言·javascript·ecmascript
野生技术架构师14 小时前
一线大厂Java面试八股文全栈通关手册(含源码级详解)
java·开发语言·面试
Q一件事15 小时前
R语言制图-相关性及关系网络图
开发语言·r语言
坊钰15 小时前
Java 死锁问题及其解决方案
java·开发语言·数据库
551只玄猫16 小时前
【数学建模 matlab 实验报告1】
开发语言·数学建模·matlab·课程设计·实验报告
三道渊17 小时前
C语言:文件I/O
c语言·开发语言·数据结构·c++