C 如何解释*((字符*)&a)

C 如何解释*((字符*)&a),c,endianness,C,Endianness,我看到了一种了解平台端性的方法是这个程序,但我不理解它 #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; } #包括 内部主(空) { INTA=1; 如果(*((char*)&a)==1)pr

我看到了一种了解平台端性的方法是这个程序,但我不理解它

#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;
}
#包括
内部主(空)
{
INTA=1;
如果(*((char*)&a)==1)printf(“小端点”\n);
else printf(“Big-Endian\n”);
系统(“暂停”);
返回0;
}
考试做什么

  • a的地址
  • 将其转换为
    char*
  • 取消引用此
    char*
    ,这将为您提供
    int
  • 检查它的值-如果它是
    1
    ,则它是little endian。否则-大

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

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

    int
    几乎总是大于一个字节,并且通常跟踪体系结构的字大小。例如,32位体系结构可能具有32位整数。因此,给定典型的32位整数,4个字节的布局可能是:

       00000000 00000000 00000000 00000001
    
    或先使用最低有效字节:

       00000001 00000000 00000000 00000000
    
    char*是一个字节,所以如果我们把这个地址转换成char*我们也会得到上面的第一个字节

       00000000
    


    因此,通过检查第一个字节,我们可以确定体系结构的终结性。

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

    因此,如果最低阶字节首先出现,那么平台就是小端,否则就是大端


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

    这只适用于
    sizeof(int)>1
    的平台。例如,我们假设它是2,并且a
    char
    是8位

    基本上,对于小尾端,数字1作为16位整数如下所示:

    00000001 00000000
    
    但对于big endian,它是:

    00000000 00000001
    
    因此,首先代码设置
    a=1
    ,然后:

    *( (char*)&a ) == 1)
    
    获取
    a
    的地址,将其视为指向
    char
    的指针,并取消对其的引用。因此:

    • 如果
      a
      包含一个小的endian整数,那么将得到
      00000001
      部分,当被解释为
      char

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

    您可以通过使用
    int16\u t
    int8\u t
    而不是
    int
    char
    来改进此代码。或者更好,只需检查
    htons(1)!=1

    • 您可以将整数视为4字节的数组(在大多数平台上)。小端整数的值为
      01 00
      ,大端整数的值为
      00 00 01
    • 通过执行
      &a
      可以获得该数组的第一个元素的地址
    • 表达式
      (char*)&a
      将其强制转换为单个字节的地址
    • 最后,
      *((char*)&a)
      获取该地址包含的值
    在BigEndian中,int i=1(大小4字节)的数据将在内存中排列为:-(从低位地址到高位地址)

    而LittleEndian是:-

    00000001 -->Address 0x100
    00000000 -->Address 0x101
    00000000 -->Address 0x102
    00000000 -->Address 0x103
    
    分析上述演员阵容:-

    同样
    &a=0x100
    ,因此
    <代码> *((char *)0x100)< /代码>意味着考虑一个字节(因为4字节加载int),所以在0x100的数据将被引用。

    *( (char*)&a ) == 1 => (*0x100 ==1) that is 1==1 and so true,implying its little endian. 
    

    下面是它的分解方式:

               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
    

    基本上,cast
    (char*)&a
    将表达式
    &a
    的类型从指向
    int
    的指针转换为指向
    char
    的指针;当我们将解引用运算符应用于结果时,它会给出存储在
    a
    的第一个字节中的值

    @DonalFellows可能重复不确定是否在dup上,此问题已找到代码,并想知道它是如何工作的。潜在的dup只是问一个关于如何检测endianness的一般问题。可能的重复也请注意,结果不是很可靠,因为big endian和little endian不是唯一的选项,一些疯狂的硬件会以不同的方式进行整数和浮点运算,一些CPU可以在运行时进行配置。请注意,这张漂亮的图形颠覆了尾端的感觉:它移动了计算指针指向的明显位置,而不是对整数的字节进行重新排序。您似乎翻转了字节中的位顺序以及整数中的字节顺序!非常非常感谢,我可能按下了home按钮而不是end:)
    int
    在64位Linux上是32位的。@JamesMcLaughlin我不知道,谢谢。我软化了语言。C89 2.2.4.2和C99 5.2.4.2.1要求
    sizeof(int)>1
    ,通过要求
    int_MIN
    int_MAX
    的值超过
    char
    的容量,所以尽管您的警告是正确的,但它却是完全正确的。更有趣的是,这段代码在不是big-endian或small-endian的middle-endian系统上工作不正确。(尽管这种系统的频率很小,如果你不得不问它们是什么,你可能不必关心它们。:-)
    00000000 -->Address 0x100
    00000000 -->Address 0x101
    00000000 -->Address 0x102
    00000001 -->Address 0x103
    
    00000001 -->Address 0x100
    00000000 -->Address 0x101
    00000000 -->Address 0x102
    00000000 -->Address 0x103
    
    *( (char*)&a ) == 1 => (*0x100 ==1) that is 1==1 and so true,implying its little endian. 
    
               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