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. 多线程共享变量
相关推荐
小妖66613 小时前
力扣(LeetCode)- 60. 排列序列
算法·leetcode·职场和发展
im_AMBER13 小时前
Leetcode 70 好数对的数目 | 与对应负数同时存在的最大正整数
数据结构·笔记·学习·算法·leetcode
小妖66613 小时前
力扣(LeetCode)- 74. 搜索二维矩阵
算法·leetcode·矩阵
Liangwei Lin13 小时前
洛谷 U311289 矩阵距离
线性代数·算法·矩阵
Dev7z16 小时前
基于MATLAB数学形态学的边缘检测算法仿真实现
算法·计算机视觉·matlab
风筝在晴天搁浅1 天前
代码随想录 718.最长重复子数组
算法
kyle~1 天前
算法---回溯算法
算法
star _chen1 天前
C++实现完美洗牌算法
开发语言·c++·算法
hzxxxxxxx1 天前
1234567
算法
Sylvia-girl1 天前
数据结构之复杂度
数据结构·算法