我创建了一个unsigned int和unsigned char。然后我赋予-10值,并且char保持无符号并给出值246,但unsigned int取-10值。
#include <stdio.h>
int main ()
{
unsigned char a;
unsigned int b;
a=-10;
b=-10;
printf("%d\t%d\n", a,b);
}
编译并执行我有这个:
246 -10
我不知道为什么unsigned int stills签名,以及为什么char是无符号的。
阅读本书&#34; C编程语言第2版&#34;我可以看到默认情况下char可以取决于机器。
(我正在运行NetBSD
作为操作系统。)
为什么int在我声明为unsigned int时签名,为什么char取值为246?
这是一个编译器或系统运行&#34;功能&#34; ?
答案 0 :(得分:1)
将无符号整数传递给%d
时,这是未定义的行为。 Wrong format specifier is UB.
如果你给一个无符号变量赋一个负值,那就很好了,这个值将取模UINT_MAX + 1
(或UCHAR_MAX + 1
),所以(-10) % (UCHAR_MAX + 1)
= 256 - 10 = 246,并且b
是4294967296 - 10 = 4294967286。无包对整数溢出是环绕的。
当printf
解释这些数字时,它会发现246适用于%d
,signed int
的格式说明符和4294967286被重新解释为-10。就是这样。
答案 1 :(得分:1)
当您将-10
分配给unsigned char
变量时,该值会以UCHAR_MAX + 1
模式减少,从而在您的平台上生成246
。在大多数平台上使用格式unsigned char
打印%d
值都可以。该值隐式转换为int
,这是%d
格式的正确类型。所以,你可以看到246
。
当您将-10
分配给unsigned int
变量时,该值会以模UINT_MAX + 1
为模,这会产生一些较大的值(取决于您unsigned int
的范围平台)。使用格式unsigned int
打印如此大的INT_MAX
值(大于%d
)会导致未定义的行为。输出毫无意义。
答案 2 :(得分:0)
%d
是用于打印signed int
的说明符,因此并不奇怪。请改用%u
。
http://www.cplusplus.com/reference/cstdio/printf/
当您为无符号变量指定负值时,您将会溢出。这就是你得到奇怪价值的原因。
printf("%d", a)
表示将变量a
和解释的内容作为带符号的int。
哦,顺便说一下。您正在导致未定义的行为,这意味着没有理由问为什么会发生某些事情。未定义的行为将始终未定义。不惜一切代价避免它。请注意,唯一未定义的是printf语句。将超出范围的值分配给无符号变量是已定义的行为。然而,事实恰恰相反。 int a = UINT_MAX
会导致未定义的行为。