我正试图以一种可移植的方式将int中的字节转换为一系列字符,以跨所有小端系统。
我有以下代码:
#include <stdio.h>
int
main()
{
int i = 0xabcdef12;
printf("i: %xn", i);
char a, b, c, d;
a = (i >> 000) & 0xFF;
b = (i >> 010) & 0xFF;
c = (i >> 020) & 0xFF;
d = (i >> 030) & 0xFF;
printf("a b c d: %x %x %x %xn", a , b, c, d);
if(a == 0x12)
printf("a is 0x12n");
if(b == 0xef)
printf("b is 0xefn");
if(c == 0xcd)
printf("c is 0xcdn");
if(d == 0xab)
printf("d is 0xabn");
if(a == 0xffffff12)
printf("a is 0x12n");
if(b == 0xffffffef)
printf("b is 0xffffffefn");
if(c == 0xffffffcd)
printf("c is 0xffffffcdn");
if(d == 0xffffffab)
printf("d is 0xffffffabn");
return 0;
}
这段代码在使用-Wall时编译时没有任何警告。
运行时给出:
i: abcdef12
a b c d: 12 ffffffef ffffffcd ffffffab
a is 0x12
b is 0xffffffef
c is 0xffffffcd
d is 0xffffffab
以下是一些gcc打印:
Breakpoint 1, main () at test.c:14
14 if(a == 0x12)
(gdb) p/x a
$1 = 0x12
(gdb) p/x b
$2 = 0xef
(gdb) p/x c
$3 = 0xcd
(gdb) p/x d
$4 = 0xab
我很确定我做错了什么。如果你能回答以下几个问题,这将真正帮助我了解发生了什么:
- 一个字符的值怎么可能大于0xff
- 什么
& 0xff
位掩码不起作用 - 为什么gdb报告正确的值
如果任何人都有一种可靠的(独立于系统的,但endianes并不重要)从int到char[]的方法,那就太好了。
这里有一个快速修复程序。
更改:
char a, b, c, d;
至
unsigned char a, b, c, d;
原因是char
已在您的系统上签名。当你将a
、b
、c
、d
转换为printf()
时,它们将升级为int
。它们是符号扩展的。这就是为什么你得到了所有领先的ff
s。
GDB报告的值是正确的,因为它直接读取chars
。(因此没有整数提升)
比较时,a
、b
、c
和d
升级为int
。由于它们都是char
,所以最高有效位被视为符号位。升级到CCD_ 17将MSB填充到更高位。
0x12
的MSB为0,0xef
、0xcd
和0xab
的MSB均为1。这就是为什么升级后你会得到0x00000012
,而不是0xffffffef
、0xffffffcd
和0xffffffab
。
如果您更改
char a, b, c, d;
进入
unsigned char a, b, c, d;
然后你就能得到你所期望的。