1

自从我开始用 C 编程已经有一段时间了,但是我仍然对unsigned. 如果我们编译这段代码:

#include <stdio.h>

int main(int argc, char **argv)
{
    unsigned int x = -1;

    return 0;
}

gcc 和 VC++ 都不会引发任何错误,甚至不会发出关于将负数与unsigned.

我的问题是它unsigned做任何内部工作还是只是向程序员暗示这个值不应该是负数?

4

7 回答 7

3

这不仅仅是一个提示。以下两个片段的行为应该不同:

签名整数:

int x = -1;
printf("%d\n", x > 0);  // prints 0

无符号整数:

unsigned int x = -1;
printf("%d\n", x > 0);  // prints 1

你可能会想出另外 5 个签名很重要的例子。例如,与操作员一起右移>>

于 2012-09-02T16:27:03.627 回答
2

用于-Wsign-conversion获得警告gcc

gcc4.7.1 中,-Wsign-conversion既不是也不-Wall属于 -Wextra.

另请注意,C 标准不需要对此初始化发出警告。

于 2012-09-02T16:28:12.567 回答
2

unsigned不是static,或extern等限定符。它是类型的一部分。constinline

int并且unsigned int是两种完全不同的类型。你永远不会找到一个unsigned int可以容纳负数的。还要注意intsigned int是完全相同的类型。对于 来说,这是一个稍微不同的故事char,但我会再讲一遍。

分配-1给一个无符号整数是一个常见的技巧,可以将它设置为它可以容纳的最大值。

于 2012-09-02T16:42:20.223 回答
0

尝试通过以下方式在 gcc 中启用警告:gcc -Wall -o out input.c

unsigned int和 normal之间的另一个区别intint使用 4 字节的范围:–2,147,483,648 到 2,147,483,647,unsigned使用 4 字节的范围:0 到 4,294,967,295。您不必存储有关符号(最高位)的信息,因此您可以分配更大的值并且应用程序将正常工作。

于 2012-09-02T16:25:59.993 回答
0

unsigned会影响整数溢出、比较和按位移位行为。这不仅仅是一个“提示”,它不应该是负面的。

于 2012-09-02T16:29:11.943 回答
0

((unsigned int) -1)等价于(UINT_MAX)( <limits.h>),因为从负值到无符号值的转换保证通过模运算完成。

C11 § 6.3.1.3 有符号和无符号整数

2 否则,若新类型为unsigned,则在新类型所能表示的最大值的基础上反复加减一,直到该值在新类型的范围内。

于 2012-09-02T18:36:09.860 回答
-1

用于计算的内部(机器级)指令有带符号和无符号版本,例如乘法mul(用于无符号)和imul(有符号)。当您将变量声明为无符号或有符号时,编译器会选择它们。

于 2012-09-02T16:28:00.277 回答