volatile、extern、static关键字

一、volatile

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

示例:

cpp 复制代码
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,然后继续执行。
cpp 复制代码
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

volatile int flag = 0;

void* thread1_func(void* arg) {
    // 执行一些操作
    sleep(2); // 模拟操作延迟
    flag = 1; // 设置flag
    return 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关键字用于声明变量或函数是在另一个文件中定义的,并且可以在多个文件之间共享。它告诉编译器变量或函数的定义在其他地方。

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

变量声明示例:

cpp 复制代码
// file1.c
int shared_variable = 10;

// file2.c
extern int shared_variable;

void function() {
    // 可以访问shared_variable
    shared_variable = 20;
}

函数声明示例:

cpp 复制代码
// 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,以此类推。

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

静态全局变量示例:

cpp 复制代码
// 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
}

静态函数示例:

cpp 复制代码
// file1.c
static void static_function() {
    // 仅在file1.c中可见
}

void public_function() {
    static_function();
}

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

cpp 复制代码
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++),控制变量和函数的作用域和生命周期。
相关推荐
2601_962203511 分钟前
【SpringBoot3】面向切面 AspectJ AOP 使用详解
开发语言·前端·python
程序员大雄学编程4 分钟前
微积分43. 无穷积分入门:从概念到Python实战可视化
开发语言·python·学习·微积分
何以解忧,唯有..4 分钟前
LangChain 中 Pydantic 格式输出:结构化输出的完整指南
java·开发语言·langchain
郝学胜-神的一滴13 分钟前
C++11 工程级应用 06:自己造一个类似Python的Range迭代器
开发语言·c++·windows·python·程序人生·microsoft
zh_xuan24 分钟前
c++ jthread
开发语言·c++·jthread
旧梦952725 分钟前
Java 捕获多个异常:从基础语法到最佳实践
java·开发语言
海兰1 小时前
【 Python 量化交易】开篇
开发语言·python·信息可视化·量化交易
神仙别闹1 小时前
基于C++ WinPcap 的网络抓包软件
网络·c++·php
我的xiaodoujiao2 小时前
Django 基础知识详细图文教程 4-Django 视图定义与使用
开发语言·数据库·后端·测试工具·django·sqlite
l1t2 小时前
DeepSeek总结的DuckDB在 CI 中为 release 和 glibc CLI 构建启用 LTO - #24225
开发语言·数据库·ci/cd·duckdb