Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C中的无符号值_C_Printf_Unsigned - Fatal编程技术网

C中的无符号值

C中的无符号值,c,printf,unsigned,C,Printf,Unsigned,我有以下代码: #include <stdio.h> int main() { unsigned int a = -1; int b = -1; printf("%x\n", a); printf("%x\n", b); printf("%d\n", a); printf("%d\n", b); printf("%u\n", a); printf("%u\n", b); return 0; } 我可以看到

我有以下代码:

#include <stdio.h>

int main() {
    unsigned int a = -1;
    int b = -1;
    printf("%x\n", a);
    printf("%x\n", b);

    printf("%d\n", a);
    printf("%d\n", b);

    printf("%u\n", a);
    printf("%u\n", b);
    return 0;
}
我可以看到,根据传递给
printf
函数的值,值被解释为有符号或无符号。在这两种情况下,字节是相同的(
ffffffff
)。那么,
无符号的
字是什么意思?

在十六进制中,它不能得到负值。所以它显示为ffffffff

unsigned int a = -1;
printf("%d\n", a);  // UB

使用无符号版本(当您知道包含的值为非负值时)的优点是,有时计算机会为您发现错误(当负值分配给变量时,程序将“崩溃)。正如您所注意到的,对于4字节整数,
-1
4294967295
具有完全相同的位表示。这一切都是关于你想如何对待他们,或是看他们


语句
无符号int a=-1
正在将
-1
转换为2的补码,并在
a
中分配位表示。
printf()
表示您正在将
-1
补码
存储到
a的内存中
它只不过是
0xffffffff
4294967295

因此,当您使用
%x或%u
格式说明符打印它时,您将获得该输出

通过指定变量的有符号性来决定可存储值的最小和最大限制

unsigned int
类似:范围从
0到4294967295
int
:范围从
-2147483648到2147483647


有关签名的更多信息,请参考将
int-1
分配给
未签名的
:由于
-1
不适合范围
[0…UINT\u MAX]
,因此会添加
UINT\u MAX+1的倍数,直到答案在范围内。显然,
UINT_MAX
在OP的机器上是
pow(2,32)-1或429496725
,因此
a
的值为4294967295

unsigned int a = -1;
printf("%d\n", a);  // UB
“%x”
“%u”
说明符需要一个匹配的
无符号的
。由于这些不匹配,“如果转换规范无效,则行为未定义。
如果任何参数不是相应转换规范的正确类型,行为未定义“C11§7.21.6.1 9。printf说明符不会更改
b

printf("%x\n", b);  // UB
printf("%u\n", b);  // UB
“%d”
说明符需要匹配的
int
。因为这些不匹配,所以更多的UB

unsigned int a = -1;
printf("%d\n", a);  // UB
鉴于未定义的行为,这些结论不受支持


在这两种情况下,字节都是相同的(ffffffff)

即使使用相同的位模式,不同的类型也可能有不同的值
ffffff
作为一个
无符号的
的值为4294967295。作为一个
int
,根据有符号整数编码,它的值为-1、-2147483647或TBD。作为一个
浮点
它可能是一个

无符号字是什么意思

unsigned
存储范围为
[0…UINT\u MAX]
的整数。它从来没有负值。如果代码需要非负数,请使用
无符号
。如果代码需要一个计数数,可以是+、-或0,请使用
int


更新:要避免编译器警告将有符号的
int
分配给无符号的
,请使用以下命令。这是一个被求反的
无符号
1u
,其定义如上所述。其效果与
-1
相同,但向编译器传达了直接意图

unsigned int a = -1u;

请参阅:简短的回答是“如果最高有效位为
1
,则将其解释为负整数”。@rvillablanca“如果我可以看到有符号变量打印为有符号或无符号”-您不能,使用
%d
打印无符号值和使用
%u
%x
打印有符号值是未定义的行为。您的一些printf语句是UB,它主导了这个问题。这是未定义的行为。没有人能理解“打印ffffffff可以打印为有符号-1或无符号4294967295”的意思。如果先将值强制转换为正确的类型,则相同的位模式在printf中可以使用相应的格式被视为有符号或无符号。为
无符号
变量指定负值的可能重复行为有明确定义。
无符号i=-1始终将INT_MAX值指定给i。你关于UB的陈述是不正确的。请重新阅读你引用的段落。TL;DR:遵循语法的任何转换说明符都是“有效的”。换句话说,在
printf(“%d”,“foo”)
中,说明符“%d”在引用段落所指的意义上是有效的。当然,尝试将字符串打印为int是不正确的,但这并不是因为您认为的原因。相反,“如果允许,将执行适当的类型升级或转换”,并且由于不允许从字符串到int的类型升级或转换,因此将变为UB。@AnorZaken Answer进行了修改,以强调printf说明符和参数类型不匹配。Err,为什么没有为无符号整数
b
?@Columbo和
int b=-1定义说明符%u
b
不是无符号整数,而是值为-1的
int
。使用不匹配的说明符打印是UB-正数有一个例外,但这不适用于这里。贝卡,这太不可读了