【问题标题】:Is the address of an int the same in little and big endian?小端和大端中int的地址是否相同?
【发布时间】:2013-11-26 14:50:09
【问题描述】:

例如,如果我有一个整数数组。

int arr[3] = { 1 , 2 , 3 } ;
unsigned char * a = ( unsigned char* )&arr[0] ;

printf("%d " , *( int* )a ) ;
a += sizeof( int ) ;
printf("%d " , *( int* )a ) ;
a += sizeof( int ) ;
printf("%d " , *( int* )a ) ;

这段代码会在大端和小端架构上产生1 2 3吗?

我假设这适用于包括结构在内的所有类型?

【问题讨论】:

  • 由于存储,即写入和后续读取是int指针,它应该打印1 2 3。你试过这个并找到不同的答案吗?
  • @Ganesh 我没有大端机器。
  • 问题的大/小端方面也适用于结构,但是将示例扩展到结构可能会引入填充问题。
  • @alk 怎么样,sizeof 不处理这个问题吗?
  • 请原谅我不清楚。此问题的当前示例代码中存在 no 填充问题。 “将您的示例扩展到结构可能会引入填充问题”的意思是说处理结构类似示例可能 引入填充问题。

标签: c pointers endianness memory-address


【解决方案1】:

是的,如果您要存储 int 值,然后稍后重新检索这些相同的 int 值,那么它们在下面的存储方式(例如,大/小端)都无关紧要。

例如,假设你定义

int a = 0xaabbccdd;

在小端系统上,这将在内存中存储为 0xdd 0xcc 0xbb 0xaa。在大端系统上,这将被存储为 0xaa 0xbb 0xcc 0xdd。但是,当您将此内存视为 int 时,它将始终被视为 0xaabbccdd。现在,如果您查看原始内存的子部分(例如,内存中 int 值的子部分),字节序就会发挥作用。例如,假设您只从存储 int 的内存位置读取前两个字节:

int *ptr = &a;
short firstTwoBytesInMemory = *(short*)ptr;

firstTwoBytesInMemory 的值在小端系统上为 0xccdd,在大端系统上为 0xaabb。

更新: 为了进一步扩展,结构本质上是基本类型的集合(例如,字节、整数、指向其他事物的指针等)。这些原始类型通常在内存中连续布局(对齐等有一些例外)。因此,适用于上述 int/short 示例的相同规则适用于原始类型的集合(例如,结构)。

如果您开始访问变量的子部分,那么架构的字节序就很重要,但是如果您始终以正确的类型(例如 int、double 等)处理事物的整体,那么事物的存储方式下面应该是透明的。

【讨论】:

  • @Klas 他将内存中的字节转换为整数(在与构造原始数据相同的整数边界上)
  • 不是“以MSB优先查看”,而是以MSB最为显着! int 中的字节没有“第一个”或“最后一个”,它只是一个 int - 它可以以架构选择的任何方式存储(例如以某种疯狂的方式交织数字)。
  • 没错,我想说的是(也许以一种不太清楚的方式),如果您存储整数,然后稍后将它们作为整数读取,则在您创建它们的相同整数边界上' 将始终获得相同的值。但是,如果您开始读取部分原始数据,您将获得什么取决于架构如何存储其内存。
  • 如果 int 存储在磁盘上或通过网络发送到具有相反字节序的机器,则需要考虑切换。
【解决方案2】:

你的假设是正确的。 在给定的架构上,除非您明确使用字节序转换函数来修改值,否则不会出现字节序问题。 当您在 LE 和 BE 架构(通常是 PC 和便携式设备)之间交换信息时,会出现字节序问题。 在您的情况下,您将 int* 转换为 (unsigned char*),然后在取消引用指针时将 (unsigned char*) 转换回 (int*) 这不会影响实际数据(int 数组的内容)。转换是在指针上进行的,而不是在 int 本身上。

【讨论】:

    猜你喜欢
    • 2014-02-14
    • 2013-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-24
    • 1970-01-01
    • 1970-01-01
    • 2011-04-29
    相关资源
    最近更新 更多