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

在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. 多线程共享变量
相关推荐
INGNIGHT13 分钟前
1897 · 会议室 3(扫描线)
数据结构·算法
All for pursuit.15 分钟前
【贪心-2】253.会议室 II
数据结构·c++·算法·leetcode
垆边人似月.16 分钟前
华为机考题(一):质数因子
算法·华为
迷途之人不知返1 小时前
算法系列5:位运算
算法
牢姐与蒯1 小时前
c++加餐之位图
c++·算法·哈希
Omics Pro1 小时前
预测性虚拟细胞中显式机理算子
大数据·数据库·人工智能·python·算法·机器学习·自然语言处理
驭渊的小故事1 小时前
算法实战:滑动窗口、素数枚举与字符串模拟(三道经典题解)
java·算法
牢姐与蒯1 小时前
位运算及其oj题
c++·算法
小蒋学算法11 小时前
算法-交替删除操作后最后剩下的整数-跟着灵茶山艾府学算法
数据结构·算法
荆棘鸟智能11 小时前
林业遥感长势评估怎么做?从NDVI时序分析到LiDAR蓄积量回归
人工智能·算法·智慧林业