volatile、extern、static关键字

一、volatile

  volatile关键字用于告诉编译器,一个变量的值可能在程序执行期间以不可预见的方式发生变化,编译器不应对该变量进行优化。即:编译器不能对这个变量进行优化,必须每次都从内存中读取它的值,而不能缓存到寄存器中。

示例: 

volatile int flag = 0;void check_flag() {while (!flag) {// 等待flag改变}// flag改变后继续执行
}

        void check_flag():这个函数是用来检查 flag 的值,如果 flag0,函数会一直在 while 循环中等待,直到 flag 被修改为非零值。

        { // 等待flag改变 }:在这个循环体内没有任何操作,表示函数在等待 flag 发生改变。由于 flag 被声明为 volatile,每次检查 flag 的值时,都会从内存中读取最新的值,而不是使用寄存器中的缓存值。

常用于多线程编程: 一个线程可能会改变 flag 的值,而另一个线程在 check_flag 函数中等待 flag 的改变。示例如下:

假设我们有两个线程:

  • 线程1:负责执行某些操作,并在完成后将 flag 设置为1。
  • 线程2:负责调用 check_flag 函数,等待 flag 的值变为1,然后继续执行。
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>volatile int flag = 0;void* thread1_func(void* arg) {// 执行一些操作sleep(2); // 模拟操作延迟flag = 1; // 设置flagreturn NULL;
}void* thread2_func(void* arg) {check_flag(); // 等待flag改变printf("Flag has been set to 1, continuing...\n");return NULL;
}int main() {pthread_t thread1, thread2;pthread_create(&thread1, NULL, thread1_func, NULL);pthread_create(&thread2, NULL, thread2_func, NULL);pthread_join(thread1, NULL);pthread_join(thread2, NULL);return 0;
}

在这个示例中,线程2会一直等待,直到线程1将 flag 设置为1,然后线程2继续执行并打印消息。 

        总结来说,volatile 关键字确保 flag 的变化能被及时察觉到,避免编译器的优化导致程序逻辑错误。 

 二、 extern

  extern关键字用于声明变量或函数是在另一个文件中定义的,并且可以在多个文件之间共享。它告诉编译器变量或函数的定义在其他地方。 

  • 跨文件变量:用于在多个源文件中共享全局变量。
  • 函数声明:在头文件中声明函数,以便在其他源文件中调用。

变量声明示例:

// file1.c
int shared_variable = 10;// file2.c
extern int shared_variable;void function() {// 可以访问shared_variableshared_variable = 20;
}

函数声明示例: 

// header.h
extern void shared_function(void);// file1.c
#include "header.h"
void shared_function() {// 函数实现
}// file2.c
#include "header.h"
void another_function() {shared_function(); // 调用共享函数
}

三、static 

static关键字有多种用途,具体取决于它是用在变量、函数还是类成员上。

  • 静态局部变量:在函数内声明的静态变量在函数调用之间保持其值,并且仅在第一次调用时初始化。
  • 静态全局变量:在文件范围内声明的静态变量只能在该文件中访问(即具有文件范围)。
  • 静态函数:静态函数只能在声明它的文件中访问。
  • 类的静态成员(C++):类的静态成员属于类,而不是类的任何实例。它们在所有实例间共享。

静态局部变量示例:

        每次调用 counter 函数时,count 的值都会在上一次的基础上增加 1,并打印当前的 count 值。因此,第一次调用 count1,第二次调用 count2,以此类推。 

void counter() {static int count = 0; // 只初始化一次count++;printf("Count: %d\n", count);
}

静态全局变量示例:

// file1.c
static int file_scope_variable = 0;void function() {file_scope_variable++;
}// file2.c
extern void function();void another_function() {function(); // 不能直接访问file_scope_variable
}

静态函数示例:

// file1.c
static void static_function() {// 仅在file1.c中可见
}void public_function() {static_function();
}

类的静态成员示例(C++): 

class MyClass {
public:// 类内静态成员变量声明static int static_member;static void static_method() {// 可以访问static_member}
};// 类外定义静态成员
int MyClass::static_member = 0;int main() {MyClass::static_member = 5;// 通过类名访问和修改静态成员变量MyClass::static_method();// 通过类名调用静态成员函数// 也可以通过对象访问静态成员变量和函数MyClass obj;obj.static_member = 10;obj.static_method();return 0;
}

四、总结 

  • volatile:告诉编译器不要优化这个变量,变量可能随时改变。
  • extern:声明变量或函数在其他文件中定义,用于跨文件访问。
  • static:用于声明局部静态变量、文件范围的静态全局变量和静态函数,以及类的静态成员(C++),控制变量和函数的作用域和生命周期。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/25504.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Vue 2看这篇就够了

Vue 2 技术文档 Vue.js 是一款用于构建用户界面的渐进式框架。与其他重量级框架不同的是&#xff0c;Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层&#xff0c;不仅易于上手&#xff0c;还便于与第三方库或既有项目整合。而 Vue.js 2&#xff08;以下简称 Vue…

Vue2基础:.sync修饰符的使用,认识,作用,本质案例演示,实现父子之间的通信。

.sync的作用&#xff1a; 可以实现子组件与父组件数据的双向绑定&#xff0c;简化代码。 与v-model的不同点,prop属性名可以自定义&#xff0c;不要一定要用value. .sync的本质&#xff1a; 就是&#xff1a;属性名和update&#xff1a;属性名合写。 下面我们进行代码演示…

探索智慧景区票务系统的架构与应用

随着旅游业的迅速发展&#xff0c;智慧景区票务系统已经成为提升景区管理效率、优化游客体验的重要工具。智慧景区票务系统的架构设计与应用&#xff0c;将现代信息技术与景区管理相结合&#xff0c;为景区的门票销售、入园管理和游客服务提供了全新的解决方案。本文将深入探讨…

每天一个数据分析题(三百五十六)-图表决策树

图表决策树中将图表分成四类&#xff0c;分别是&#xff1f; A. 比较类 B. 序列类 C. 构成类 D. 描述类 数据分析认证考试介绍&#xff1a;点击进入 题目来源于CDA模拟题库 点击此处获取答案

【西瓜书】9.聚类

聚类任务是无监督学习的一种用于分类等其他任务的前驱过程&#xff0c;作为数据清洗&#xff0c;基于聚类结果训练分类模型 1.聚类性能度量&#xff08;有效性指标&#xff09; 分类任务的性能度量有错误率、精度、准确率P、召回率R、F1度量(P-R的调和平均)、TPR、FPR、AUC回归…

滑动窗口算法:巧妙玩转数据的窗外世界

✨✨✨学习的道路很枯燥&#xff0c;希望我们能并肩走下来! 文章目录 目录 文章目录 前言 一 滑动窗口是什么&#xff1f; 二 相关题目解析 1. 长度最小的子数组 &#x1f973;题目解析 &#x1f973;算法原理 ✏️思路1 暴力枚举出所有子数组之和 ✏️思路2 滑动窗…

docker-compose部署mysql+nginx+redis

docker部署 参考&#xff1a; docker部署mysqlnginxredis docker-compose部署mysqlnginxredis mysql 1、创建docker-compose-mysql.yml version: "3" services:mysql:image: mysql:5.7restart: alwayscontainer_name: mysqlports:- 3306:3306volumes:- /home/my…

LangChain开发【NL2SQL】应用

前言 关于LangGraph的简单介绍&#xff0c;请参考这篇博客&#xff1a; LangGraph开发Agent智能体应用【基础聊天机器人】-CSDN博客 对比LangChain实现NL2SQL 关于用LangChain开发NL2SQL的Agent应用&#xff0c;在这篇博客提供了完整的代码实现&#xff1a; LangChain开发…

AI网络爬虫:批量爬取豆瓣图书搜索结果

工作任务&#xff1a;爬取豆瓣图书搜索结果页面的全部图书信息 在ChatGPT中输入提示词&#xff1a; 你是一个Python编程专家&#xff0c;要完成一个爬虫Python脚本编写的任务&#xff0c;具体步骤如下&#xff1a; 用 fake-useragent库设置随机的请求头&#xff1b; 设置chr…

深拷贝浅拷贝解析,从原理理解深拷贝

这块应该都有过比较深刻的了解了。今天加深下印象和查漏补缺下。 浅拷贝&#xff1a; let original { a: 1, b: { c: 2 } };//这边定一个obj&#xff0c;来供拷贝 let shallowCopy Object.assign({}, original);// let shallowCopy { ...original }; 创建一个浅拷贝对象拷贝…

NFT 智能合约实战-快速开始(1)NFT发展历史 | NFT合约标准(ERC-721、ERC-1155和ERC-998)介绍

文章目录 NFT 智能合约实战-快速开始(1)NFT发展历史国内NFT市场国内NFT合规性如何获得NFT?如何查询NFT信息?在 OpenSea 上查看我们的 NFT什么是ERC721NFT合约标准ERC-721、ERC-1155和ERC-998 对比ERC721IERC721.sol 接口内容关于合约需要接收 ERC721 资产 onERC721Received…

Nginx面试题精选及参考答案(3万字长文)

目录 什么是Nginx,它主要用于哪些场景? Nginx和Apache有什么区别? 描述一下Nginx的事件驱动模型。 Nginx如何处理静态文件和动态请求? 什么是反向代理,Nginx如何实现反向代理? 如何在Linux系统中安装Nginx? Nginx的主要配置文件有哪些? 如何修改Nginx的配置以实…

软考初级网络管理员_01_计算机系统基础知识(硬件)单选题

1.在字长为16位、32位、62位或128位的计算机中&#xff0c;字长为()位的计算机数据运算精度最高。 16 32 64 128 2.8位、16位、32位和64位字长的计算机中&#xff0c;()位字长计算机的数据运算精度最高。 9 8 16 64 3.声卡的性能指标主要包括-和采样位数:在采样位数分…

如何随机化列表中的元素?

一、技术难点 在Python中&#xff0c;随机化列表中的元素通常指的是对列表进行洗牌&#xff08;shuffle&#xff09;操作&#xff0c;即在不改变列表中元素数量的前提下&#xff0c;随机改变元素的顺序。这个过程看似简单&#xff0c;但在实际实现中需要考虑一些技术细节和难点…

插入排序(Insertion_sort)

最简单的一种排序 基本思想就是从第一个元素开始&#xff0c;每次排列一个元素&#xff0c;一直排列到结尾 例如&#xff1a; 3 1 4 5 7 2 6 第一个元素不用排序&#xff0c;从第二个开始 因为3 > 1所以直接将3覆盖到1上 3 3 4 5 7 2 6 而1用一个变量先…

【CMake】install用法

以前一直不清楚install的具体作用&#xff0c;现在明白了&#xff0c;其实就是把你的文件&#xff08;生成的二进制&#xff0c;源代码或者任意&#xff09;给复制&#xff08;也可以说安装&#xff09;到指定路径。 将二进制安装到Bin文件夹 比如我生成了一个test程序&#…

【教学类-64-02】20240610色块眼力挑战(二)-2-25宫格色差10-100(10倍)(星火讯飞)

背景需求 以下的色块眼里挑战需要人工筛选图片&#xff0c;非常繁琐。 【教学类-64-01】20240607色块眼力挑战&#xff08;一&#xff09;-0-255随机底色-CSDN博客文章浏览阅读446次&#xff0c;点赞12次&#xff0c;收藏5次。【教学类-64-01】20240607色块眼力挑战&#xff…

Linux安装Docker | 使用国内镜像

环境 CentOS7 先确认能够上网 curl www.baidu.com返回该输出说明网络OK 步骤一&#xff1a;安装gcc 和 gcc-c yum -y install gccyum -y install gcc-c步骤二&#xff1a;安装Docker仓库 yum install -y yum-utils接下来配置yum的国内镜像 yum-config-manager --add-re…

tomcat服务器之maxHttpHeaderSize

背景&#xff1a;在OA流程表单中&#xff0c;填写了200条数据&#xff0c;一提交&#xff0c;秒报400错误&#xff0c;且请求没有打到后端中&#xff08;无报错日志&#xff09;&#xff0c;一开始以为是谷歌浏览器的问题&#xff0c;可百度上关于这个错误的解决方案都是清除缓…

转让北京劳务分包地基基础施工资质条件和流程

地基基础资质转让流程是怎样的?对于企业来说&#xff0c;资质证书不仅是实力的证明&#xff0c;更是获得工程承包的前提。而在有了资质证书后&#xff0c;企业才可以安心的准备工程投标&#xff0c;进而在工程竣工后获得收益。而对于从事地基基础工程施工的企业&#xff0c;需…