什么时候整数的符号真的重要?

And*_*eKR 4 c signedness

由于在C中定义了转换和操作的方式,因此使用有符号或无符号变量似乎很少:

uint8_t u; int8_t i;

u = -3;    i = -3;
u *= 2;    i *= 2;
u += 15;   i += 15;
u >>= 2;   i >>= 2;

printf("%u",u); // -> 2
printf("%u",i); // -> 2
Run Code Online (Sandbox Code Playgroud)

那么,是否有一套规则可以告诉变量的符号在哪些条件下确实有所不同?

jpa*_*cek 9

在这些情况下,这很重要:

  • 除法和模数:-2/2 = 1,-2u/2 = UINT_MAX/2-1,-3%4 = -3,-3u%4 = 1
  • 转移.对于负的有符号值,结果>><<是实现定义或未定义,分别为.对于无符号值,始终定义它们.
  • 关系-2 < 0,-2u > 0
  • 溢出.如果ff具有签名类型x+1 > x,则编译器可以假定它始终为true . x


Nic*_*ynt 8

是.签名将影响C中的大于和小于运算符的结果.请考虑以下代码:

unsigned int a = -5;
unsigned int b = 7;

if (a < b)
    printf("Less");
else
    printf("More");
Run Code Online (Sandbox Code Playgroud)

在此示例中,"更多"输出不正确,因为编译器将-5转换为非常高的正数.

这也会影响您使用不同大小的变量进行算术运算.再次考虑这个例子:

unsigned char a = -5;
signed short b = 12;

printf("%d", a+b);
Run Code Online (Sandbox Code Playgroud)

返回的结果是263,而不是预期的7.这是因为-5实际上被编译器视为251.溢出使您的操作对于相同大小的变量正常工作,但是在扩展时,编译器不会扩展无符号变量的符号位,因此它将它们视为在较大空间中的原始正表示.研究两个人的赞美是如何起作用的,你会看到这个结果来自哪里.


Alo*_*ave 6

它会影响您可以存储在变量中的值范围.