系统相关
首页 > 系统相关> > c – 间接操作符是否改变了内存表示?

c – 间接操作符是否改变了内存表示?

作者:互联网

好吧,我觉得这很愚蠢,但为什么下面的代码输出不同的行?

要打印第一行,我将地址写入数组的第一个字节,将其解释为指向uint16_t的指针,取值并逐个打印它的位.

对于第二行,我采用指向第一个字节的指针,将其解释为指向uint8_t的指针,取值并逐个打印它的位.然后对第二个字节执行相同的操作.

因为我不修改为数组分配的内存,只能以不同的方式解释它,我期望输出相同,但字节的顺序是不同的.

我可能会错过一些东西,但我唯一的猜测是间接运算符做了我不期望的事情.

#include <iostream>
#include <string.h>


 int main() {
   uint8_t u[2];
   u[0] = 170;
   u[1] = 85;

  for(int i = 15; i >= 0; --i) {
    printf( "%u", (((*((uint16_t*)u)) >> i) & 0x0001));
  }
  printf( "\n");
  for(int i = 7; i >= 0; --i) {
    printf( "%u", (((*((uint8_t*)u)) >> i) & 0x01));
  }
  for(int i = 7; i >= 0; --i) {
    printf( "%u", (((*((uint8_t*)(u + 1))) >> i) & 0x01));
  }
}

Outout

0101010110101010 
1010101001010101

更新#1:请忽略分配,是示例代码不适用于每个操作系统,但它只是一个简化的示例.

更新#2:我知道字节序,但我错过的是逻辑与物理位表示.在上面的示例中,即使物理表示未更改,我也会打印受字节序影响的逻辑表示.非常感谢@ john-kugelman解释这一点.

解决方法:

在基于Intel的平台上,数字存储在little endian order中.最低有效字节是第一个,最重要的是最后一个.这与我们传统阅读数字的方式相反.如果我们用小端而不是大端序写入数字,那么一二二三将写成3201而不是1023.

当您将字节数组中的字节解释为16位整数时,第一个字节(170)被解释为最低有效字节,第二个字节(85)被解释为最高有效字节.但是当你自己打印字节时,你会以相反的顺序打印它们.这就是不匹配的来源.

Endianness是特定于平台的属性.大多数非英特尔架构使用更“自然”的大端序.对我们来说不幸的是,基于英特尔的架构是最常见的.实际上,几乎所有网络流量都是大端,也称为“网络字节顺序”.当基于Intel的机器在因特网上通话时,它们在发送和接收数据期间进行大量的字节交换.

I expected this missmatch to happen if I print that uint16_t itself. What I don’t understand is why it happens when I try to get its bits.

通过位屏蔽和移位操作读取其位不会从左到右读取存储器中的物理位,它会从最重要到最不重要的位置读取逻辑位.在小端架构上,最重要到最不重要的等同于从右到左的顺序.

另请注意,字节顺序意味着交换字节,而不是位.在小端架构中,比特不是交换的,字节是.位不能交换,因为它们不能单独寻址.你只能用轮班和面具来接待他们.

标签:uint8t,c,memory
来源: https://codeday.me/bug/20190724/1527000.html