volatile、extern、static关键字

2024-06-10 17:04

本文主要是介绍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++),控制变量和函数的作用域和生命周期。

这篇关于volatile、extern、static关键字的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1048747

相关文章

OC中的static关键字

1.修饰局部变量      1.只会初始化一次      2.全局只会存在一份内存      3.不会改变自身的作用域,比如原来是局部变量现在的话依然是局部变量      4.生命周期延长(直到程序结束,这个局部变量才会被销毁)      2.  修饰全局变量     static 修饰的全局变量 在整个工程 中只会存在一份     只可以在当前的.h .m文件中才可以访问。 如果单纯全局变量的

#ifndef #define #endif 和 extern C的作用

ifndef #define #endif 防止头文件被重复引用 被重复引用”是指一个头文件在同一个cpp文件中被include了多次,这种错误常常是由于include嵌套造成的。比如:存在a.h文件#include "c.h"而此时b.cpp文件导入了#include “a.h” 和#include "c.h"此时就会造成c.h重复引用。 头文件被重复引用引起的后果: 有些头文件重复引用只是

PHP中静态(static)调用非静态方法详解

1.PHP中可以静态调用非静态方法么? 今天我被问到PHP中可不可以使用 className::methodName() 的方法来调用一个没有声明static的方法。在我的印象中,我好像是见过这种用法,但又有些不确定。大家都知道,在手册或者教程里,方法被分为静态方法 和非静态方法,通常我们静态调用的方法,肯定是静态方法。 那如果我们调用了非静态方法会怎么样呢?首先做测试。 1

php函数内的static变量以及类static方法

A: 函数内的static变量 static静态变量的理解 静态变量 类型说明符是static。 静态变量属于静态存储方式,其存储空间为内存中的静态数据区(在 静态存储区内分配存储单元),该区域中的数据在整个程序的运行期间一直占用这些存储空间(在程序整个运行期间都不释放),也可以认为是其内存地址不变,直 到整个程序运行结束(相反,而auto自动变量,即动态局部变量,属于动态存储类别,占动态存

【C++】初始化列表、匿名对象、static成员、友元、内部类

文章目录 一、初始化列表构造函数体赋值初始化列表explicit关键字 二、匿名对象三、static成员四、友元友元函数友元类 五、内部类六、练习题 一、初始化列表 构造函数体赋值 实际上,构造函数的函数体内,并不是对 对象 初始化的地方,而是对成员变量进行赋值。因为初始化只能初始化一次,而构造函数体内可以多次赋值。 class Date{public:Date(int

abstract的method是否可同时是static,是否可同时是native,是否可同时是synchronized

1,abstract的method是否可同时是static,是否可同时是native,是否可同时是synchronized 都不可以,因为abstract申明的方法是要求子类去实现的,abstract只是告诉你有这样一个接口,你要去实现,至于你的具体实现可以是native和synchronized,也可以不是,抽象方法是不关心这些事的,所以写这两个是没有意义的。然后,static方法是不会被覆

synchronized、volatile、Lock详解

在Java并发编程过程中,我们难免会遇到synchronized、volatile和lock,其中lock是一个类,而其余两个则是Java关键字。以下记录了小博开发过程中对这三者的理解,不足之处请多指教。 关于线程与进程请参考博文 以操作系统的角度述说线程与进程 synchronized   synchronized是Java中的关键字,是一种同步锁。有以下几种用法: 1、修饰方

oracle 5-关键字comment

1.对表的说明 comment on table table_name is 'comments_on_tab_information'; 2.对表中列的说明 comment on column table.column_name is 'comments_on_col_information';

不需要new关键字创建实例?jQuery是如何做到的

这篇文章是jQuery源码专栏的开篇文章了,有人会问为什么都2024年了, 还要研究一个已经过时的框架呢,其实,jQuery对比vue和react这种响应式框架,其在使用上算是过时的,毕竟直接操作DOM远不如操作虚拟DOM来的方便,但是jQuery的框架设计和对于操作的封装以及浏览器的兼容这些,太值得我们去学习了。   这个专栏更新的速度不会快,这框架代码我是刚开始进行了解,所以只能边看边查

C# 中的静态关键字

C# 语言中的 static 关键字用于声明静态类和静态类成员。静态类和静态类成员(如构造函数、字段、属性、方法和事件)在只需要一个对象(类或类成员)副本并在类型(和成员)的所有实例(对象)之间共享时很有用。 让我们简化一下。假设您有一个类“CSharpSite”,它代表 C#Site网站、其属性及其功能。CSharpSite 类有四个属性,Founder、YearFounded、Locatio