在C语言中,static
、const
和volatile
是三个重要的关键字,它们分别用于不同的场景,具有不同的作用。下面我将详细解释它们的作用并提供示例代码。
1. static
关键字
static
关键字有三种主要用法:
a) 修饰局部变量(改变存储期)
cpp
#include <stdio.h>
void counter() {
static int count = 0; // 静态局部变量
count++;
printf("Count: %d\n", count);
}
int main() {
counter(); // 输出: Count: 1
counter(); // 输出: Count: 2
counter(); // 输出: Count: 3
return 0;
}
作用:
-
使局部变量在函数调用之间保持其值
-
变量存储在静态存储区而非栈上
-
只初始化一次(在程序启动时)
b) 修饰全局变量(改变链接属性)
cpp
// file1.c
static int hidden_var = 42; // 静态全局变量
// file2.c
extern int hidden_var; // 错误!无法访问file1.c中的hidden_var
作用:
-
限制变量只在定义它的源文件中可见
-
防止与其他文件中的同名变量冲突
c) 修饰函数(改变链接属性)
cpp
// utils.c
static void helper() { // 静态函数
printf("Helper function\n");
}
// main.c
extern void helper(); // 错误!无法访问utils.c中的helper函数
作用:
-
限制函数只在定义它的源文件中可见
-
防止与其他文件中的同名函数冲突
2. const
关键字
const
关键字用于定义常量,表示值不可修改。
a) 修饰变量
cpp
#include <stdio.h>
int main() {
const int MAX_SIZE = 100;
// MAX_SIZE = 200; // 错误:不能修改const变量
const float PI = 3.14159;
// PI = 3.14; // 错误:不能修改const变量
printf("Max size: %d, PI: %.5f\n", MAX_SIZE, PI);
return 0;
}
b) 修饰指针
cpp
#include <stdio.h>
int main() {
int value = 10;
int another = 20;
// 指向常量的指针(指针指向的内容不可变)
const int *ptr1 = &value;
// *ptr1 = 15; // 错误:不能通过ptr1修改value
ptr1 = &another; // 正确:可以改变指针指向
// 常量指针(指针本身不可变)
int *const ptr2 = &value;
*ptr2 = 15; // 正确:可以修改指向的值
// ptr2 = &another; // 错误:不能改变指针指向
// 指向常量的常量指针(指针和内容都不可变)
const int *const ptr3 = &value;
// *ptr3 = 20; // 错误:不能修改值
// ptr3 = &another; // 错误:不能改变指向
return 0;
}
c) 修饰函数参数
cpp
#include <stdio.h>
// 参数为指向常量的指针,函数内部不能修改str指向的内容
void print_string(const char *str) {
// str[0] = 'A'; // 错误:不能修改const内容
printf("%s\n", str);
}
int main() {
char msg[] = "Hello, World!";
print_string(msg);
return 0;
}
3. volatile
关键字
volatile
关键字告诉编译器不要优化对该变量的访问,因为它可能被程序以外的因素修改。
a) 硬件寄存器访问
cpp
// 假设0x1234是硬件寄存器的地址
volatile unsigned int *reg = (unsigned int *)0x1234;
int main() {
// 读取寄存器值
unsigned int value = *reg;
// 写入寄存器
*reg = 0xABCD;
return 0;
}
b) 中断服务程序中的变量
cpp
#include <stdio.h>
volatile int flag = 0; // 可能被中断修改的变量
// 模拟中断服务程序
void interrupt_handler() {
flag = 1;
}
int main() {
while (!flag) {
// 等待中断发生
}
printf("Interrupt occurred!\n");
return 0;
}
c) 多线程共享变量
cpp
#include <stdio.h>
#include <pthread.h>
volatile int shared_counter = 0; // 多线程共享变量
void *increment(void *arg) {
for (int i = 0; i < 100000; i++) {
shared_counter++;
}
return NULL;
}
int main() {
pthread_t t1, t2;
pthread_create(&t1, NULL, increment, NULL);
pthread_create(&t2, NULL, increment, NULL);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
printf("Final counter: %d\n", shared_counter);
return 0;
}
4.总结对比
关键字 | 主要作用 | 典型应用场景 |
---|---|---|
static |
改变存储期或链接属性 | 1. 函数调用间保持状态的局部变量 2. 文件内私有的全局变量和函数 |
const |
定义常量,防止修改 | 1. 常量值定义 2. 函数参数保护 3. 只读指针 |
volatile |
防止编译器优化 | 1. 硬件寄存器访问 2. 中断服务程序 3. 多线程共享变量 |