看代码:
#include <stdio.h>
#include <stdint.h>
int main() {
char foo[512]={};
printf("%d", *((uint32_t*)foo));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我很难理解它的*((uint32_t*)foo))作用,在数组中使用不同的值我得到各种返回值。它到底指向什么,那么返回值是什么呢?
char foo[512]={};是无效语法,C 中不允许空初始化列表。 {0}如果您想初始化它,则必须使用它。(uint32_t*)foo是可疑的,因为 auint32_t* 不一定与 兼容char*。此外,char阵列可能未对齐。1)
经验法则是我们可以从任何对象指针类型转换为字符指针类型,但反之则不行。*((uint32_t*)foo)调用未定义的行为,可能有多种方式。foo可能会错位。而且它也是严格的指针别名违规(严格别名规则是什么?)。TL;DR 基本上是编译器可以自由地假设char您发布的代码中从未使用该数组,因为可以自由地假设 achar永远不会通过 a 访问uint32_t*。忽略上述所有内容 - 我们不应该这样做,因为未定义的行为意味着任何事情都可能发生 - 那么编译器很可能(但不能保证)从数组中获取 4 个字节并将char它们重新解释为uint32_t. 假设char是 8 位,那么它(可能)会根据 CPU 字节顺序这样做。也就是说,如果我们这样做char foo[512]={'A','B','C','D'};并且CPU具有小端格式,那么'D'最终将出现在uint32_t. 什么是 CPU 字节顺序?所以使用 ASCII,它会变成数字0x44434241。
请注意,这%d是错误的打印格式说明符uint32_t。您应该使用或中%u最正确的形式。printf("%"PRIu32, ...)inttypes.h
1) C17 6.3.2.3是C标准中的相关规则:
指向对象类型的指针可以转换为指向不同对象类型的指针。如果生成的指针未针对引用类型正确对齐,则行为未定义。否则,当再次转换回来时,结果应等于原始指针。