小端和大端分配

时间:2015-02-06 16:29:17

标签: c endianness

我有以下代码

int i = 321;
char ch = i;
printf("%d", ch);
二进制文件中的

i00000000 00000000 00000001 01000001,输出为65。 从上面的代码可以看出,由于char只占用1个字节的内存,因此i的前3个字节被删除,最后一个字节被分配给ch。因此结果。

我的机器是小端的。结果是ch基于底层机器的字节顺序吗?请澄清。

4 个答案:

答案 0 :(得分:7)

引用C11,6.3.1.3:

  

1当具有整数类型的值转换为另一个整数类型时   除了_Bool之外,如果值可以用新类型表示,那么   没有改变。

     

2否则,如果新类型是无符号的,则值为   通过重复加或减一个转换而来   在值之前可以在新类型中表示的最大值   在新类型的范围内。

     

3否则,新类型已签名且值不可   代表其中;结果是实现定义的还是   实现定义的信号被提出。

标准只讨论价值观。所以如果char是无符号的:321-256 = 65。如果char已签名,则行为是实现定义的。

答案 1 :(得分:1)

没有。你的答案不依赖于endian。无论字节顺序如何,编译器都将确保复制最低有效字节。

int i = 232;
int *p_i = &i;
char* pc_i = (char*)p_i;
printf("%d", (int)(*pc_i));

将在little-endian架构上给出正确的答案,但在big-endian架构上给出错误的答案。 (输入charning to char *不违反严格的别名规则)

答案 2 :(得分:1)

不,ch中的结果不是基于底层机器的字节顺序。

C没有任何字节序AFAIK的概念。 char ch = i相当于char ch = i % CHAR_MAX

如果你想查看i的最后一个或第一个字节,你可以这样做......

#include <limits.h>
#include <stdio.h>

int main()
{
  // INT_MAX = 01111111111111111111111111111
  int i = INT_MAX;

  unsigned char * front = &i;

  // This assumes ints are 4 bytes long, not a safe assumption!
  unsigned char * back = front + 3;

  printf ("%d %d", *front, *back);
  // Prints 255 127.  My machine is little-endian.
}

答案 3 :(得分:-2)

您的代码在各种计算机上的工作方式都相同。转换为char的int值将为您提供适合ch的的位。

为了查看机器的字节序,您必须重新指向指向int的指针。

int i = 321;
char ch = *((char *)&i);

或以巧妙的方式使用工会。如果你的机器挑剔对齐,你甚至可以用这些东西产生访问冲突......

union Foo { int i; char c; } foo; foo.i = 321; char ch = foo.c;