C语言关键字详解:static、const、volatile

在C语言中,staticconstvolatile是三个重要的关键字,它们分别用于不同的场景,具有不同的作用。下面我将详细解释它们的作用并提供示例代码。

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. 多线程共享变量
相关推荐
没有bug.的程序员6 分钟前
Sentinel 流控原理深度解析:构建高可用微服务的底层架构
java·算法·微服务·云原生·架构·sentinel·负载均衡
深圳佛手7 分钟前
IVFFlat 与 HNSW 算法介绍与对比
人工智能·算法·机器学习
Q741_14711 分钟前
C++ 栈 模拟 力扣 227. 基本计算器 II 题解 每日一题
c++·算法·leetcode·模拟
徐新帅14 分钟前
CSP 二进制与小数进制转换专题及答案解析
c++·算法
wxdlfkj14 分钟前
从硬件极限到算法补偿:构建微米级工件特征“在机测量”闭环系统的技术路径解析
人工智能·算法·机器学习
王璐WL15 分钟前
【数据结构】二叉树经典算法题和选择题
数据结构·算法
jllllyuz16 分钟前
MATLAB多目标优化:SQP算法实现
数据结构·算法·matlab
im_AMBER19 分钟前
数据结构 14 【复习】二叉树中序遍历 | 线索二叉树 | 树、森林、二叉树的转换 | 层次遍历二叉树
数据结构·笔记·学习·算法
im_AMBER19 分钟前
Leetcode 88 K 和数对的最大数目
数据结构·c++·笔记·学习·算法·leetcode
hetao173383743 分钟前
2025-12-25~26 hetao1733837的刷题记录
c++·笔记·算法