我有以下代码
int i = 321;
char ch = i;
printf("%d", ch);
二进制文件中的 i
为00000000 00000000 00000001 01000001
,输出为65
。
从上面的代码可以看出,由于char
只占用1个字节的内存,因此i
的前3个字节被删除,最后一个字节被分配给ch
。因此结果。
我的机器是小端的。结果是ch
基于底层机器的字节顺序吗?请澄清。
答案 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;