整数在内存中是如何存储的?

3

我在阅读有关大端/小端的文章时感到困惑。

代码如下:

#include <iostream>
using namespace std;

int i = 12345678;

int main()
{
    char *p = (char*)&i;  //line-1

    if(*p == 78)  //line-2
        cout << "little endian" << endl;
    if(*p == 12)
        cout << "big endian" << endl;

}

问题:

  1. 在第一行中,我能使用 static_cast<char*>(&i) 进行转换吗?

  2. 在第二行中,根据代码,如果是小端模式,则 78 存储在最低字节中,否则 12 存储在最低字节中。但是我认为,i = 12345678; 将以二进制形式存储在内存中。

    如果是小端模式,则 i 的二进制的最后一个字节将存储在最低字节中,但我不明白如何保证 i 的最后一个字节是 78

    就像,如果 i = 123;,那么 i 的二进制是 01111011,它能保证在小端模式下,23 存储在最低字节中吗?


1
你的代码会失败,因为你混淆了十进制和十六进制。在数字前加上“0x”,它就能正常工作了。 - Mike DeSimone
2
你可能想要的是:int i = 0x12345678; - Martin York
4个回答

9
  1. 我更倾向于使用reinterpret_cast

  2. 小端和大端是指字节(即8位数量)在内存中的存储方式,而不是两个十进制数。如果i的值为0x12345678,你可以检查0x780x12来确定字节序,因为两个十六进制数字对应一个字节(在我编程的所有硬件上都是如此)。


你能否详细说明“检查0x78和0x12以确定字节序”的含义? - user195488
如果 i 是十六进制,那么 0x12 0x34 0x56 0x78 会分别按顺序占用一个字节吗? - Alcott
不是真的。我希望你能详细说明如何检查。 - user195488
1
@Alcott:没错,两个十六进制数字正好是一个字节。这是因为一个十六进制数字可以储存16个不同的值,而16² = 256 = 2^8。 - Fred Foo
@CodeMonkey:检查在OP的代码中。如果您在源代码中使用“0x”前缀,则可以正常工作。 - Fred Foo

4
这里涉及到两个不同的概念:
  1. 数字以二进制格式存储。8位代表一个字节,整数可以使用1、2、4甚至8或1024字节,取决于它们运行的平台。
  2. 字节顺序是内存中的顺序(从最不重要的开始-LE,或从最重要的开始-BE)
现在,12345678是一个十进制数,其二进制(base2)表示为101111000110000101001110。这并不容易检查,主要是因为base2表示不能精确地分组成一个十进制数字。(不存在整数x使得2x=10)。16进制数字更容易适应:24=16和28=162=256。
因此,十六进制数0x12345678形成字节0x12-0x34-0x56-0x78。现在很容易检查第一个是0x12还是0x78。
(注意:12345678的十六进制表示为0x00BC614E,其中0xBC为188,0x61为97,0x4E为78)

1
  1. static_cast 是一种新式替代旧式 C 风格转换的方法,但在这里不适用;reinterpret_cast 用于完全更改数据类型。

  2. 这段代码根本行不通——字节不能容纳偶数个十进制数字!十进制数的数字与存储在内存中的字节不是一一对应的。例如,十进制数 500 可以被存储在两个字节中,如 0x01F4。"01" 代表 256,"F4" 是另一个 244,总共为 500。你不能说 "500" 中的 "5" 在这两个字节中的任何一个——没有直接的对应关系。


您的意思是不能保留偶数位小数吗?不太明白,先生。 - Alcott
似乎我不能使用 static_cast,因为我得到了一个错误:“error: invalid static_cast from type ‘int’ to type ‘char’”。 - Alcott
2
static_cast 用于相关类型之间的转换。reinterpret_cast 用于任意指针类型之间的转换。 - Fred Foo
@Alcott - 你比你想象中理解得更好 - 二进制数“1111”的十进制值是多少?那是几位数字? - Hugh Jones
1
@Alcott - 正如答案所示,12345678(十进制)存储为0x00BC614E。除非您指的是0x12345678(十六进制),否则您必须查找字节“00”或“4E”。 - StuartLC
2
通过“不具有偶数位小数”我是指十进制数的数字与存储在内存中的字节不是一对一匹配的。例如,十进制数500可以以两个字节的形式存储为0x01F4。其中的“01”代表256,“F4”代表244,总共是500。你不能说“500”中的“5”在这两个字节中的任何一个中——它们之间没有直接对应关系。 - Ernest Friedman-Hill

0

应该是

unsigned char* p = (unsigned char*)&i;

你不能使用 static_cast。只能使用 reinterpret_cast。


1
另外,您不能使用静态转换。 - Kerrek SB

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接