我正在浏览2braces.com上的C test,并对第一个问题感到困惑。
#include<stdio.h>
int main(){
int a = 130;
char *ptr;
ptr = (char *)&a;
printf("%d ",*ptr);
return 0;
}
答案说它的输出是-126。但IMO,它取决于:little-endian env中的输出应为-126,big endian env中的输出应为0。我是对的吗?
如果代码想要测试char溢出问题,可能会更加严格:
#include<stdio.h>
int main(){
int a = 130;
char c = a;
printf("%d ",c);
return 0;
}
BTW,我看到很多使用char和int联合来测试字节序的示例代码,将char *
用于整数是不是更简单?
我想验证我的猜测,但我没有一个大端环境。
答案 0 :(得分:2)
但IMO,它取决于:little-endian env中的输出应为-126, 大端环境中的0和0我是对的吗?
排序。
如果同时检查-126和130,vs 0,(char可以是有符号或无符号),现在大约有99%的设备,这将有效。但严格来说,这两种价值都无法保证。原因包括:
顺便说一句,我看到很多使用char和int结合的示例代码 测试字节顺序
虽然我需要查看它,但是不能保证char将位于int的第一个字节。如果是这样,这是另一个需要考虑的问题。
答案 1 :(得分:1)
这段代码:
#include <stdio.h>
int main() {
int a = 130;
char *ptr;
ptr = (char *)&a;
printf("%d ",*ptr);
return 0;
}
没有未定义或未指定的行为,除了130
以(隐式签名)char
访问时会以某种方式恰好成为陷阱值的相当模糊的可能性,但有很多可能结果:
-126
,其中char已签名且表示为2的补码130
,其中char是无符号的。0
,其中char已签名或未签名0
。如果-126
由一个,两个字节表示,则可以是130
或int
或其他内容sizeof(int)
为1的平台。可能所有可寻址的原始值都有sizeof
1 - 这些根本就没有任何字节序其中一些是模糊的,但小端和大端计算机确实存在,并且在ARM处理器上char
默认为unsigned
。
为了不使事情复杂化,应使用unsigned
类型完成endianess检测。
如果您使用固定大小类型
,则union
测试有效
union {
uint32_t the_int;
uint8_t fragments[4];
}
您不会在运行时测试计算机的字节顺序!代码必须只为一个和一个字节序编译,所以你无论如何都可以在编译时完成它。需要在运行时完成的实际字节顺序检查仅涉及从文件或进程间通信中读取的数据结构。