本文主要是介绍volatile、extern、static关键字,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
一、volatile
volatile
关键字用于告诉编译器,一个变量的值可能在程序执行期间以不可预见的方式发生变化,编译器不应对该变量进行优化。即:编译器不能对这个变量进行优化,必须每次都从内存中读取它的值,而不能缓存到寄存器中。
示例:
volatile int flag = 0;void check_flag() {while (!flag) {// 等待flag改变}// flag改变后继续执行
}
void check_flag():
这个函数是用来检查flag
的值,如果flag
为0
,函数会一直在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
值。因此,第一次调用 count
为 1
,第二次调用 count
为 2
,以此类推。
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关键字的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!