C编程 - 指针地址字节拆分

时间:2018-04-24 14:25:54

标签: c pointers

我有以下变量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文档? 我有这个工作,但我不知道它是如何工作的。

由于

1 个答案:

答案 0 :(得分:5)

通常,您可以通过指向字符类型的指针访问C中的任何数据类型,例如unsigned char*uint8_t*。如果将var转换为这样的字符指针,则会得到指向第一个字节的指针:

unsigned char* cptr = (unsigned char*)&var;

然后,您可以通过执行*cptrcptr[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编译器上,特别是启用了高优化。