使用指针时的奇怪行为

时间:2013-08-28 22:13:36

标签: c pointers pointer-arithmetic

我有一个带有一些二进制数据的文件如下。

aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55         
aa 55 aa 55 36 65 fb 5f 1e 92 d8 1b 55 f7 fb 5f         
1e 92 d8 1b

我想提取值55 36 65 fb 5f 1e

如果我使用以下代码。

temp_1 = (data_ptr[offset]);
val = temp_1 << 40;

temp_1 = (data_ptr[offset + 1]);
val |= temp_1 << 32;

temp_1 = (data_ptr[offset + 2]);
val |= temp_1 << 24;

temp_1 = (data_ptr[ts_offset + 3]);
val |= temp_1 << 16;

temp_1 = (data_ptr[ts_offset + 4]);
val |= temp_1 << 8;

temp_1 = (data_ptr[ts_offset + 5]);
val |= temp << 0;

printf("read value %"PRIx64" \n",val);

此printf的结果是

3665fb5f1e92

现在我也尝试使用单个64位ptr强制转换操作来计算相同的值。

val = *(uint64_t*)(data_ptr + ts_offset);
printf("read value %"PRIx64" \n",val);

上述代码的输出是

1bd8921e5ffb6536 

如果你在这里检查最不重要的48位921e5ffb6536

与第一个结果相比,它是倒置的。我正在使用普通的英特尔处理器。为什么这种行为?这是预期的。

2 个答案:

答案 0 :(得分:2)

在移动值的代码中,您正在读取最低地址的最高字节(偏移0处的位40-47)。我猜你的第二种情况是在x86机器上运行,因此从最低地址读取最低字节(因为这是x86的定义方式,就像许多其他处理器一样,它们被称为“little-endian”机器)。

如果你想要那个特定顺序的字节,在little-endian机器上,你将不得不逐个获取字节并移位(如果你想要一个完整的64位值,它可能已经可以使用在x86上的byteswap指令,但我怀疑它是否足够值,因为当你需要通过移动和屏蔽你实际上不需要的16位来“撤消”它。

答案 1 :(得分:1)

预期会有这种行为。

整数的字节顺序保存在内存中会有所不同。从最低有效字节到大多数(小端)或最高有效字节到最小。 (大端)。

Google“endian”获取大量信息或阅读“Guliver Travel's”。