这是什么指针魔法

what pointer magic is this

我正在学习C。我开始理解指针和类型转换。我正在遵循一些指南和示例,并且我 运行 贯穿此声明:

uint32_t *sp;
...
*(uint32_t*)sp = (uint32_t)somevalue;

这里发生了什么?第一个星号对我来说特别神秘。

第一个星号取消引用 sp 指针,以便将 somevalue 的值分配给指针对象。

我想知道为什么演员表,因为这个

*sp = (uint32_t) somevalue;

如果spuint32_t *类型就可以了。

第一个星号是 indirection operator

基本上就是get/access指针所在地址的

引用 C11 标准,章节 §6.5.3.2,地址和间接运算符

The operand of the unary * operator shall have pointer type.

The unary * operator denotes indirection. If the operand points to a function, the result is a function designator; if it points to an object, the result is an lvalue designating the object. [...]

第一个星号在被转换为指向 uint32_t 的指针后取消引用 sp,因此 somevalue 被写入该位置。

但是,强制转换是不必要的,因为 sp 已经是指向 uint32_t 的指针。此外,如果 somevalue 是数字类型,则右侧的转换也是不必要的,因为右值将隐式转换为左值的类型。

你的困惑源于这不是一个声明,而是一个赋值语句:

/* This is the declaration of sp as a pointer to uint32_t */
uint32_t *sp;

/* This is an assignment statement setting *sp to somevalue */
*(uint32_t*)sp = (uint32_t) somevalue;

它看起来很像一个声明,因为对左值进行了不必要的转换,这使得它看起来有点像在声明类型。

分解:

*(uint32_t*)sp 

基本上是说将 sp 视为指向 uint32_t 的指针((uint32_t *) 是一个 cast 表达式 ),并取消引用结果.

所以,

*(uint32_t*)sp = (uint32_t)somevalue;

表示,"take somevalue, convert it to type uint32_t, and store the result to the thing sp points to, and treat that thing as though it were also a uint32_t."

请注意 sp 上的转换是多余的;您已经 已经 将其声明为指向 uint32_t 的指针,因此赋值可以写成

*sp = (uint32_t) somevalue;