C/C++ use of int or unsigned int

C/C++ use of int or unsigned int

本文关键字:int or unsigned of use C++      更新时间:2023-10-16

在大量的代码示例、源代码、库等。在我看来,当unsigned int更有意义时,我看到了int的使用。

我经常在for循环中看到这种情况。请看下面的例子:

for(int i = 0; i < length; i++)
{
    // Do Stuff
}

为什么你要用int而不是unsigned int ?是不是因为懒惰——人们不愿意输入unsigned ?

使用unsigned可能会引入难以发现的编程错误,通常最好使用带符号的int来避免这些错误。例如,当您决定向后迭代而不是向前迭代时,可以这样写:

for (unsigned i = 5; i >= 0; i--) {
    printf("%dn", i);
}

另一种是如果你在循环中做一些数学运算:

for (unsigned i = 0; i < 10; i++) {
    for (unsigned j = 0; j < 10; j++) {
        if (i - j >= 4) printf("%d %dn", i, j);
    }
}

使用unsigned引入了这类错误的可能性,并且实际上没有任何好处。

通常是懒惰或缺乏理解。

当值不应该为负时,我总是使用unsigned int。这也可以用于文档目的,指定正确的值应该是什么。

恕我直言,断言使用"int"比使用"unsigned int"更安全是完全错误的,是一种糟糕的编程实践。

如果您使用Ada或Pascal,您将习惯于使用更安全的做法,即为值指定特定的范围(例如,整数只能是1,2,3,4,5)。

如果length也是int,那么您应该使用相同的整数类型,否则在比较语句中混合有符号和无符号类型时会发生奇怪的事情。大多数编译器会给你一个警告。

你可以继续问,为什么要签署length ?嗯,这可能是历史上的。

同样,如果您决定反转循环,即

for(int i=length-1;i>=0 ;i--)
{
   // do stuff
}

如果使用无符号整型,逻辑就会中断。

我选择在编程时尽可能明确。也就是说,如果我打算使用一个值总是正的变量,那么就使用unsigned。这里很多人提到"很难发现bug",但很少有人给出例子。考虑以下使用unsigned的示例,不像这里的大多数帖子:

enum num_things {
    THINGA = 0,
    THINGB,
    THINGC,
    NUM_THINGS
};
int unsafe_function(int thing_ID){
    if(thing_ID >= NUM_THINGS)
        return -1;
    ...
}
int safe_function(unsigned int thing_ID){
    if(thing_ID >= NUM_THINGS)
        return -1;
    ...
}
int other_safe_function(int thing_ID){
    if((thing_ID >=0 ) && (thing_ID >= NUM_THINGS))
        return -1;
    ...
}
/* Error not caught */
unsafe_function(-1);
/* Error is caught */
safe_function((unsigned int)-1);

在上面的例子中,如果一个负值作为thing_ID传入会发生什么?在第一种情况下,您会发现负值不大于或等于 NUM_THINGS,因此函数将继续执行。

在第二种情况下,您实际上会在运行时捕获这个错误,因为thing_ID的签名强制条件执行无符号比较

当然,您可以做一些类似other_safe_function的事情,但这似乎更像是使用有符号整数而不是更显式地使用unsigned开始。

我认为最重要的原因是如果你选择unsigned int,你可以得到一些逻辑错误。实际上,您通常不需要unsigned int的范围,使用int更安全。

这段小代码是用例相关的,如果你调用一些向量元素,那么原型是int,但是在c++中有很多现代的方法可以做到这一点。对于(const auto &v: vec){}或迭代器,在某些计算中,如果没有减法/得到负数,你可以并且应该使用unsigned(更好地解释预期值的范围),有时正如这里发布的许多示例所示,你实际上需要int,但事实是这完全取决于用例和情况,没有一个严格的规则适用于所有用例,强制使用一个会有点愚蠢…