你能用little endian概念解释以下源代码的输出吗?

时间:2017-01-20 16:56:17

标签: c pointers

任何人都可以向我解释以下基于小端和大端的输出。我已经阅读了很多关于这个概念的文章和帖子,但是在做了这么多东西后我也无法获得关于这个主题的任何内容一切都在我的头上。

任何帮助将不胜感激。谢谢! 源代码: 将int的大小视为两个字节,将char的大小视为一个字节

int main()
{
   int a = 300;    
   char *b = (char *)&a;
   *++b = 2;
   printf("%d ",a);
   return 0;
}  

2 个答案:

答案 0 :(得分:2)

首先,这在技术上不是标准规定的,因为整数类型的表示是依赖于实现的,并且直接更改int值中的字节可能会导致陷阱表示。

话虽如此,你声明你的实现使用(你声明了一些,我假设剩下的):

  • 字符为8位(字节和字符按定义相同大小)
  • int(16位)的2个字节
  • 无填充位 - 在2的补码中有15个值位和1个符号位

这里没有陷阱表示,允许访问字节级别的任何对象

现在让我们看看会发生什么:

a是十进制的300,十六进制是0x12C

在小端表示法中,(char *) &a将指向包含2个字符{ 0x2c, 1 }的数组 - 在大尾数中它将是{ 1, 0x2C }

下一个*++b = 2首先增加指针,并将2分配给指向的值。

等效字符数组现在是小端的{ 0x2c, 2 }和大端的{ 1, 2 }

让它转换回int,我们得到小端的0x22C = 556和大端的0x102 = 258

答案 1 :(得分:0)

既然你提到你已经读过它,我假设你知道小端存储最小值字节的基础知识和大端存储最高值字节(我们发现直观)。

现在考虑你的计划。 a为300.二进制为300:

00000000 00000000 00000001 00101100

然而,在小端机器上,它将存储如下。

00101100 00000001 00000000 00000000

现在您有一个分配了a

引用的字符
char *b = (char *)&a;

所以最初b指向00101100。

接下来你做

   *++b = 2;

意义增量b,然后将值2分配给增量后指向的位置。

因此,b在增量后指向00000001,并在那里指定2。因此它变成00000010.

现在看到整个数字,在Little endian机器上它看起来像这样,

00101100 00000010 00000000 00000000

在小端程序机器上转换为556 - 这是您应该期望的输出。

您可以使用相同的示例来理解大端情况。