我有以下变量var,它是一个无符号的32位值。 我正在研究一个小端系统。
unsigned long var = 1;
// Representation: 00000000 00000000 00000000 00000001
现在我想通过以下方式访问第一个和最后一个16位:
(((unsigned short*)&var)[0])) => 00000000 00000001
(((unsigned short*)&var)[1])) => 00000000 00000000
这种类型的指针地址类型拆分是否有任何C文档? 我有这个工作,但我不知道它是如何工作的。
由于
答案 0 :(得分:5)
通常,您可以通过指向字符类型的指针访问C中的任何数据类型,例如unsigned char*
或uint8_t*
。如果将var
转换为这样的字符指针,则会得到指向第一个字节的指针:
unsigned char* cptr = (unsigned char*)&var;
然后,您可以通过执行*cptr
或cptr[0]
来引用该指针以获取内容 - 这意味着同样的事情。在一个小端系统上,你现在有一个指向最低有效字节的指针。 cptr[1]
将在此之后给出字节,依此类推。
然而这只 保证适用于角色类型!不能使用像unsigned short
这样的其他类型 - 这会产生所谓的“严格别名违规”。 What is the strict aliasing rule?意思是如果你有这样的代码:
unsigned long var = 1;
*(unsigned short*)&var = 123;
if(var == 1)
printf("Look mom, I violated strict aliasing!");
然后编译器可以自由地生成执行printf语句的代码。或者它也可以像您期望的那样更改var
并且不执行printf。或者它可以崩溃和燃烧:它是未定义的行为,任何事情都可能发生。像这样的错误经常出现在gcc编译器上,特别是启用了高优化。