C语言进阶——一文带你深度了解“C语言关键字”中篇(七)

 

本篇文章记录我学习C语言进阶知识——C语言关键字,旨在记录分享,希望我的分享能带给你不一样的收获!

目录

一、关键字----volatile

1、volatile 关键字的作用

2、volatile 的使用示例 

二、关键字---extern

 1、关键字extern作用

 2、关键字extern的用法示例

1. 变量声明

2. 函数声明


一、关键字----volatile

volatile 是易变的、不稳定的意思。很多人根本就没见过这个关键字,不知道它的存在。
也有很多程序员知道它的存在,但从来没用过它。我对它有种“杨家有女初长成,养在深闺
人未识” 的感觉。

在C语言中,volatile 是一个关键字,用于告诉编译器某个变量的值可能会在程序的执行过程中被外部因素改变。这个关键字的使用能够确保编译器不会对这样的变量进行优化,以避免潜在的逻辑错误。

volatile 关键字和 const 一样是一种类型修饰符, 用它修饰的变量表示可以被某些编译器
未知的因素更改,比如操作系统、硬件或者其它线程等。遇到这个关键字声明的变量,编
译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问。

1、volatile 关键字的作用

防止优化

  • 编译器在优化代码时可能会假设变量的值在程序的某个时刻不会改变。因此,它可能会将变量的值缓存起来,减少对内存的访问。使用 volatile 修饰的变量会强制编译器每次都从内存中读取变量的值,而不是使用缓存的值。

硬件寄存器访问

  • 在嵌入式编程中,volatile 经常用于访问硬件寄存器,因为这些寄存器的值可能由外部硬件改变。例如,某些寄存器可能会在硬件事件发生时自动更新。

多线程编程

  • 在多线程程序中,如果一个变量在一个线程中被修改,其他线程可能需要看到这些修改。volatile 可以帮助确保变量的最新值被读取,但请注意,volatile 只是确保每次访问时从内存中读取变量的值,而不是保证线程安全。

2、volatile 的使用示例 

【1】硬件寄存器

volatile int *hardware_register = (int *)0x4000; // 硬件寄存器的地址
int value = *hardware_register; // 从硬件寄存器读取值

【2】中断服务例程

volatile int flag = 0;

void interrupt_handler() {
    flag = 1; // 中断处理程序设置标志
}

void main() {
    while (!flag) {
        // 等待中断设置 flag
    }
    // flag 被中断服务程序设置为 1,循环结束
}

【3】多线程变量(注意 volatile 并不替代其他同步机制,如互斥锁):

volatile int shared_variable = 0;

void thread_function() {
    while (shared_variable == 0) {
        // 等待其他线程改变 shared_variable
    }
    // shared_variable 被改变,退出循环
}

二、关键字---extern

extern 关键字在 C 语言中用于声明一个变量或函数是在其他文件中定义的。它告诉编译器该标识符的定义在其他地方,这样可以在多个文件间共享变量或函数。

 1、关键字extern作用

  1. 声明变量

    • 当在一个文件中声明一个外部变量时,使用 extern 来告诉编译器这个变量的定义在其他地方。
  2. 声明函数

    • extern 也用于声明函数,虽然函数声明默认是外部的,因此常常不显式使用 extern,但可以用来提高可读性。

 2、关键字extern的用法示例

1. 变量声明

file1.c 中定义变量:

int global_var = 10;

file2.c 中声明变量:

extern int global_var;  // 声明在 file1.c 中定义的变量

void print_var() {
    printf("%d\n", global_var);
}

file2.c 中使用 global_var,但不定义它,编译器会知道它在 file1.c 中定义。

2. 函数声明

file1.c 中定义函数:

void greet() {
    printf("Hello from file1.c\n");
}

 file2.c 中声明函数:

extern void greet();  // 函数声明

int main() {
    greet();  // 调用在 file1.c 中定义的函数
    return 0;
}

注意事项

  • 定义与声明

    • extern 用于声明而不是定义。定义变量时不应使用 extern,但在声明时可以使用它以指示变量的定义在其他地方。
  • 头文件

    • 通常将 extern 变量的声明放在头文件中,以便在多个源文件中共享这些变量或函数。
  • 编译链接

    • 确保所有源文件正确链接,否则可能会导致链接错误。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小小_扫地僧

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值