首页 > 解决方案 > 这个使用易失性、指针和内存分配的复杂表达式在幕后做了什么?

问题描述

我知道人们已经回答了什么是 volatile 并且 (int *) 只是强制转换,但我无法理解这个表达式的真正含义:volatile int *p = (int *)0x0

所以我们有一个指向 int 的指针 p ,显然它的值可能会意外改变。我们给它分配另一个指向内存地址 0 的指针?那么它是指向指针的指针还是我让它比它应该的更复杂?如果您能提供这样一个简单的草图,我将不胜感激,因为它有助于我理解。

草图

标签: cpointers

解决方案


volatileNULL 指针没有太多意义,因为没有人会取消引用它。

但如果我让这个表达更有意义(这是 STM32 微控制器的具体示例)

 volatile uint32_t *GPIOA_CRL = (volatile uint32_t *)0x40010800UL;

我声明了volatile指向对象GPIO_CLR的指针。uint32_t该赋值将由 unsigned long 常量定义的硬件寄存器的地址转换为指针类型。

0x40010800UL- 硬件寄存器地址

(volatile uint32_t *)- 将无符号长地址转换为指针

然后我可以设置或读取这个寄存器的值。

为什么我将此指针定义为volatile?因为它可以被硬件改变,编译器不会知道它。因此 volatile 将强制编译器在每次使用之前(当我取消引用此指针时)读取此地址下的值存储,并在每次更改后存储它。否则编译器可能会优化这些读取和写入,因为它不会在正常程序执行路径中看到它的影响。


推荐阅读