4

我看到了一种了解平台字节顺序的方法是这个程序,但我不明白

#include <stdio.h>
int main(void)
{
  int a = 1;
  if( *( (char*)&a ) == 1) printf("Little Endian\n");
  else printf("Big Endian\n");
  system("PAUSE");  
  return 0;
}

测试有什么作用?

4

8 回答 8

9

Anint几乎总是大于一个字节,并且经常跟踪架构的字长。例如,32 位体系结构可能具有 32 位整数。所以给定典型的 32 位整数,4 个字节的布局可能是:

   00000000 00000000 00000000 00000001

或最低有效字节在前:

   00000001 00000000 00000000 00000000

char* 是一个字节,所以如果我们将此地址转换为 char* 我们将得到上面的第一个字节,要么

   00000000

或者

   00000001

因此,通过检查第一个字节,我们可以确定架构的字节序。

于 2012-08-28T14:35:12.600 回答
4

这仅适用于sizeof(int) > 1. 例如,我们假设它是 2,而 achar是 8 位。

基本上,使用 little-endian,作为 16 位整数的数字 1 如下所示:

00000001 00000000

但是对于大端,它是:

00000000 00000001

所以首先是代码集a = 1,然后是:

*( (char*)&a ) == 1)

获取 的地址a,将其视为指向 a 的指针char,然后取消引用它。所以:

  • 如果a包含一个 little-endian 整数,您将得到该00000001部分,当作为 a 插入时为 1char

  • 如果a包含一个大端整数,你会得到00000000。检查== 1将失败,代码将假定平台为大端。

您可以使用int16_tandint8_t而不是intand来改进此代码char。或者更好的是,只需检查是否htons(1) != 1.

于 2012-08-28T14:36:25.087 回答
2
  1. 取地址a
  2. 将其投射到char*
  3. 取消引用 this char*,这会给你的第一个字节int
  4. 检查它的值 - 如果它是1,那么它是小端。否则 - 大。

假设sizeof(int) == 4,则:

|........||........||........||........|    <- 4bytes, 8 bits each for the int a
| byte#1 || byte#2 || byte#3 || byte#4 |

执行步骤 1、2 和 3 时,*( (char*)&a )将为您提供第一个字节| byte#1 |.

然后,通过检查它的值,byte#1您可以了解它是大端还是小端。

于 2012-08-28T14:32:29.273 回答
2
  • 您可以将整数视为 4 个字节的数组(在大多数平台上)。小端整数将具有值01 00 00 00和大端00 00 00 01
  • 通过这样做&a,您可以获得该数组的第一个元素的地址。
  • 该表达式(char*)&a将其转换为单个字节的地址。
  • 最后*( (char*)&a )得到该地址所包含的值。
于 2012-08-28T14:37:13.437 回答
1

该程序只是将 an 占用的空间重新解释int为 s 的数组,char并假设1int 将存储为一系列字节,其中最低顺序为值为 1 的字节,其余为 0。

因此,如果最低位字节首先出现,则平台为小端,否则为大端。

这些假设可能不适用于现有的每个平台。

于 2012-08-28T14:35:38.350 回答
1
a = 00000000 00000000 00000000 00000001
    ^                                 ^
    |                                 |
    &a if big endian                  &a if little endian

    00000000                   00000001
    ^                                 ^
    |                                 |
    (char*)&a for BE                  (char*)&a for LE

    *(char*)&a = 0 for BE             *(char*)&a = 1 for LE
于 2012-08-28T14:38:28.397 回答
1

以下是它的分解方式:

           a        -- given the variable a
          &a        -- take its address; type of the expression is int *
  (char *)&a        -- cast the pointer expression from type int * to type char *
*((char *)&a)       -- dereference the pointer expression
*((char *)&a) == 1  -- and compare it to 1

基本上,强制(char *)&a转换将表达式的类型&a从指向的指针转换int为指向的指针char;当我们将解引用运算符应用于结果时,它为我们提供了存储在a.

于 2012-08-28T19:40:30.467 回答
0
*( (char*)&a )

在 BigEndian 中,int i=1(大小为 4 字节)的数据将在内存中排列为:-(从低地址到高地址)。

00000000 -->Address 0x100
00000000 -->Address 0x101
00000000 -->Address 0x102
00000001 -->Address 0x103

虽然 LittleEndian 是:-

00000001 -->Address 0x100
00000000 -->Address 0x101
00000000 -->Address 0x102
00000000 -->Address 0x103

分析上述演员阵容:-

&a= 0x100因此
*((char*)0x100)意味着考虑一次取一个字节(因为为 int 加载了 4 个字节),因此将引用 0x100 处的数据。

*( (char*)&a ) == 1 => (*0x100 ==1) that is 1==1 and so true,implying its little endian. 
于 2012-08-28T14:43:41.937 回答