C中的无符号值

rvi*_*nca 16 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;
}
Run Code Online (Sandbox Code Playgroud)

输出是:

ffffffff
ffffffff
-1
-1
4294967295
4294967295
Run Code Online (Sandbox Code Playgroud)

我可以看到根据传递给printf函数的值将值解释为有符号或无符号.在这两种情况下,字节都是相同的(ffffffff).那么,这个unsigned词是什么意思?

chu*_*ica 14

将a分配int -1unsigned:由于-1不适合该范围[0...UINT_MAX],UINT_MAX+1会添加倍数,直到答案在范围内.显然UINT_MAXpow(2,32)-1 or 429496725OP的机器上,从而a具有的价值4294967295.

    unsigned int a = -1;
Run Code Online (Sandbox Code Playgroud)

"%x","%u"符预期匹配unsigned.由于这些不匹配,"如果转换规范无效,则行为未定义.如果任何参数不是相应转换规范的正确类型,则行为未定义." C11§7.21.6.19.printf说明符不会改变b.

    printf("%x\n", b);  // UB
    printf("%u\n", b);  // UB
Run Code Online (Sandbox Code Playgroud)

"%d"符预期的匹配int.由于这些不匹配,更多UB.

    printf("%d\n", a);  // UB
Run Code Online (Sandbox Code Playgroud)

鉴于未定义的行为,不支持结论.


两种情况下,字节都相同(ffffffff).

即使使用相同的位模式,不同的类型也可能具有不同的值.ffffffffas a unsigned的值为4294967295.作为一个int依赖有符号整数编码,它的值为-1,-2147483647或TBD.因为float它可能是NAN.

什么是未签名的单词?

unsigned存储整个范围内的数字[0 ... UINT_MAX].它永远不会有负值.如果代码需要非负数,请使用unsigned.如果代码需要可能是+, - 或0的计数,请使用int.


更新:为了避免编译器警告有关分配签署intunsigned,使用下面.这是unsigned 1u被否定的 - 如上所述.效果与a相同-1,但传达给编译器的直接意图.

unsigned int a = -1u;
Run Code Online (Sandbox Code Playgroud)