我有一个二进制值存储在C中的char中,我希望将此字节转换为C中的signed int。 目前我有这样的事情:
char a = 0xff;
int b = a;
printf("value of b: %d\n", b);
标准输出的结果为“255”,所需的输出为“-1”。
答案 0 :(得分:4)
根据C99标准,
6.3.1.3有符号和无符号整数
当整数类型的值转换为 _Bool 以外的其他整数类型时,如果该值可以由新类型表示,则它将保持不变。
否则,如果新类型是无符号的,则通过重复添加或转换该值 减去一个可以在新类型中表示的最大值 直到该值在新类型的范围内。
否则,新类型已签名且值无法在其中表示;无论是 结果是实现定义或实现定义的信号。
在分配到char
之前,您需要将signed char
投放到int
,因为任何值char
都可以直接表示为int
。
#include <stdio.h>
int main(void) {
char a = 0xff;
int b = (signed char) a;
printf("value of b: %d\n", b);
return 0;
}
快速测试显示它可以在这里工作:
C:\dev\scrap>gcc -std=c99 -oprint-b print-b.c
C:\dev\scrap>print-b
value of b: -1
请注意C99标准未定义char
是否已对其进行签名或未签名。
6.2.5类型
声明为 char 类型的对象足以存储基本的任何成员 执行字符集。如果基本执行字符集的成员存储在a中 char 对象,其值保证为正。如果任何其他字符存储在 char 对象中,则结果值是实现定义的,但应在可以用该类型表示的值范围内。
...
共同调用三种类型 char , signed char 和 unsigned char 字符类型。实现应定义char具有相同的范围, 表示和行为为签名字符或 unsigned char 。
答案 1 :(得分:3)
替换:
char a = 0xff
通过
signed char a = 0xff; // or more explicit: = -1
让printf
打印-1
。
如果您不想更改a
的类型,可以在评论中添加@veer,只需将a
转换为(signed char)
,然后再将其值分配给{{1} }}
请注意,在这两种情况下,此整数转换都是实现定义的,但这是常见的实现定义行为。
答案 2 :(得分:1)
从一开始你就错了:
char a = 0xff;
如果char
为signed
,您似乎认为,此处您已经有一个超出范围的值,0xFF
是一个值为255
的无符号数量。如果您希望将char
视为已签名的号码,请使用signed char
并为其指定-1
。如果您想将其视为位模式,请使用unsigned char
并为其指定0xFF
。然后,int
的初始化将按照您的预期进行。
char
,signed char
和unsigned char
是标准三种不同类型的定义。将char
本身保留给角色,打印人类可读的内容。