打印
[STM32WL]

编程中的volatile,const意义

[复制链接]
2416|57
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
janewood|  楼主 | 2023-9-29 20:00 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
__I、 __O 、__IO是什么意思?
这是ST库里面的宏定义,定义如下:

#define __I volatile const /*!< defines 'read only' permissions */
#define __O volatile /*!< defines ‘write only’ permissions /
#define __IO volatile /!< defines ‘read / write’ permissions */

显然,这三个宏定义都是用来替换成 volatile 和 const 的,所以我们先要了解 这两个关键字的作用:

1、volatile
简单的说,就是不让编译器进行优化,即每次读取或者修改值的时候,都必须重新从内存或者寄存器中读取或者修改。

volatile的基本应用场合:
1、中断服务程序中修改的供其它程序检测的变量需要加volatile;
2、多任务环境下各任务间共享的标志应该加volatile;
3、存储器映射的硬件寄存器通常也要加volatile说明,因为每次对它的读写都可能由不同意义;

我认为这是区分C程序员和嵌入式系统程序员的最基本的问题。搞嵌入式的家伙们经常同硬件、中断、RTOS等等打交道,所有这些都要求用到 volatile变量。不懂得volatile的内容将会带来灾难。假设被面试者正确地回答了这是问题(嗯,怀疑是否会是这样),我将稍微深究一下,看一下这家伙是不是直正懂得volatile完全的重要性。
1)一个参数既可以是const还可以是volatile吗?解释为什么。
2); 一个指针可以是volatile 吗?解释为什么。
3); 下面的函数有什么错误:
int square(volatile int *ptr)
{
return *ptr * *ptr;
}

1)是的。一个例子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。也就是说,在这个函数内部是没有权限去修改这个变量的,但是在程序的其他位置可以去修改它,而导致函数内的某种响应。
2); 是的。尽管这并不很常见。一个例子是当一个中服务子程序修该一个指向一个buffer的指针时,等于是换了一片内存区域。
3) 这段代码有点变态。这段代码的目的是用来返指针ptr指向值的平方,但是,由于ptr指向一个volatile型参数,编译器将产生类似下面的代码:
int square(volatile int *ptr)
{
int a,b;
a = *ptr;
b = ptr;
return a * b;
}
由于ptr的值可能被意想不到地该变,因此a和b可能是不同的。结果,这段代码可能返不是你所期望的平方值!正确的代码如下:
long square(volatile int *ptr)
{
int a;
a = *ptr;
return a * a;
}

2、const
只读变量,即变量保存在只读静态存储区。编译时,如何尝试修改只读变量,则编译器提示出错,就能防止误修改。
const与define
两者都可以用来定义常量,但是const定义时,定义了常量的类型,所以更精确一些(其实const定义的是只读变量,而不是常量)。#define只是简单的文本替换,除了可以定义常量外,还可以用来定义一些简单的函数,有点类似内置函数。const和define定义的常量可以放在头文件里面。(小注:可以多次声明,但只能定义一次)

const与指针   
1
int me;
const int * p1=&me; //p1可变,*p1不可变 const 修饰的是 p1,即p1不可变
int * const p2=&me; //p2不可变,*p2可变 const 修饰的是 p2,即p2不可变
const int *const p3=&me; //p3不可变,*p3也不可变 前一个const 修饰的是 *p3,后一个const 修饰的是p3,两者都不可变

前面介绍了 volatile 和 const 的用法,不知道大家了解了没?了解了后,下面的讲解就更加容易了:
__I :输入口。既然是输入,那么寄存器的值就随时会外部修改,那就不能进行优化,每次都要重新从寄存器中读取。也不能写,即只读,不然就不是输入而是输出了。
__O :输出口,也不能进行优化,不然你连续两次输出相同值,编译器认为没改变,就忽略了后面那一次输出,假如外部在两次输出中间修改了值,那就影响输出
__IO:输入输出口,同上

为什么加下划线?

原因是:避免命名冲突
一般宏定义都是大写,但因为这里的字母比较少,所以再添加下划线来区分。这样一般都可以避免命名冲突问题,因为很少人这样命名,这样命名的人肯定知道这些是有什么用的。
经常写大工程时,都会发现老是命名冲突,要不是全局变量冲突,要不就是宏定义冲突,所以我们要尽量避免这些问题,不然出问题了都不知道问题在哪里。

volatile一般用在以下三个方面:

1、中断标志位

2、多线程共享的变量

3、状态寄存器


使用特权

评论回复
沙发
Stahan| | 2023-9-30 11:58 | 只看该作者
但是有好多宏定义也加下划线啊

使用特权

评论回复
板凳
sesefadou| | 2023-10-5 09:23 | 只看该作者
volatile保证了代码对特殊内存区域的读/写操作的原子性。

使用特权

评论回复
地板
alvpeg| | 2023-10-5 12:35 | 只看该作者
可以声明一个volatile const变量,表示这个变量的值在程序运行过程中不能被改变,但可能会在任何时候被意外地改变。

使用特权

评论回复
5
kkzz| | 2023-10-7 21:50 | 只看该作者
volatile和const都是C语言中非常重要的关键字,它们可以帮助编写更加安全、高效的代码。

使用特权

评论回复
6
jkl21| | 2023-10-7 22:37 | 只看该作者
声明一个变量const,意味着这个变量的值在程序运行期间不能被改变。这有助于提高代码的安全性和可靠性,防止因为不小心导致的数值修改。

使用特权

评论回复
7
Jacquetry| | 2023-10-7 22:58 | 只看该作者
加const后变量不能被改变

使用特权

评论回复
8
10299823| | 2023-10-8 16:39 | 只看该作者
正确使用"volatile"关键字可以确保数据的正确性和一致性。而"const"关键字则用于声明不可修改的常量,以增加代码的可读性和可维护性,并帮助编译器进行优化。

使用特权

评论回复
9
everyrobin| | 2023-10-8 16:52 | 只看该作者
const关键字用于声明一个常量,表示该变量的值在程序运行期间是不可改变的。

使用特权

评论回复
10
rosemoore| | 2023-10-8 18:13 | 只看该作者
"volatile"关键字用于告诉编译器该变量的值可能会在程序执行期间发生变化,因此编译器在优化代码时不应该对该变量进行优化。

使用特权

评论回复
11
iyoum| | 2023-10-8 19:20 | 只看该作者
volatile和const是两种不同的修饰符,它们分别用于声明变量的属性。

使用特权

评论回复
12
Bowclad| | 2023-10-8 22:20 | 只看该作者
const加上是不是就不能修改了啊

使用特权

评论回复
13
Undshing| | 2023-10-9 22:26 | 只看该作者
这个写程序时候用在哪里啊

使用特权

评论回复
14
nomomy| | 2023-10-10 20:31 | 只看该作者
'volatile'关键字告诉编译器,这个变量可能会被未知的因素

使用特权

评论回复
15
febgxu| | 2023-10-10 22:57 | 只看该作者
volatile通常用于声明硬件寄存器或者某些不稳定的内存区域。使用volatile声明的变量在每次访问时都会重新读取其值,以防止出现意外的值变化。

使用特权

评论回复
16
Stahan| | 2023-10-11 19:46 | 只看该作者
volatile是做什么用的啊

使用特权

评论回复
17
gygp| | 2023-10-11 21:13 | 只看该作者
const通常用于声明常量,以防止误修改。使用const声明的变量在声明时就被赋予了一个固定的值,以后的程序运行过程中不能再改变其值。

使用特权

评论回复
18
belindagraham| | 2023-10-12 20:26 | 只看该作者
volatile用于声明一个变量是易变的,即它的值可能会在程序运行过程中被意外地改变。

使用特权

评论回复
19
kmzuaz| | 2023-10-12 21:18 | 只看该作者
volatile关键字用于告诉编译器某个变量可能随时被修改,而const关键字用于声明一个不可修改的变量。它们在编程中分别用于处理不同类型的变量,以确保程序的正确性和可读性。

使用特权

评论回复
20
timfordlare| | 2023-10-12 21:33 | 只看该作者
const用于声明一个变量是常量,即它的值在程序运行过程中不能被改变。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

56

主题

1272

帖子

1

粉丝