在许多代码示例、源代码、库等中,我看到使用 int 的情况很多, 但是就我所见,使用 unsigned 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("%d\n", i);
}
另一种方法是在循环内进行一些数学计算:
for (unsigned i = 0; i < 10; i++) {
for (unsigned j = 0; j < 10; j++) {
if (i - j >= 4) printf("%d %d\n", i, j);
}
}
使用unsigned
会引入这些种类的错误,但实际上没有任何好处。
for(unsigned int i = start + 1; i-- > 0; )
或 for(unsigned int i = start; i <= start; --i)
- 后者明确地从下溢中获益。 - Aconcagua通常是因为懒惰或缺乏理解。
当数值不应为负数时,我总是使用 unsigned int。这也有助于文档说明正确的取值范围。
我认为声称使用 "int" 要比使用 "unsigned int" 更安全是错误的,这是一种不好的编程实践。
如果您曾经使用过 Ada 或 Pascal,您会习惯使用更安全的做法,即为值指定特定的范围(例如,只能是 1、2、3、4、5 的整数)。
我在编程时选择尽可能明确。也就是说,如果我打算使用一个值始终为正的变量,则使用 unsigned
。许多人提到“难以发现的错误”,但很少给出例子。请考虑以下支持使用 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
这样的方法,但这似乎更像是使用带符号整数的曲解,而不是更明确地使用无符号整数。length
也是int
,那么你应该使用相同的整数类型,否则当你在比较语句中混合有符号和无符号类型时会出现奇怪的问题。大多数编译器都会给出警告。length
应该是有符号的?嗯,这可能是历史原因。for(int i=length-1;i>=0 ;i--)
{
// do stuff
}
如果使用无符号整数,则逻辑会出现错误。
for (unsigned int i = length; i--; )
。 - M.Mfor
条件具有副作用)。每天都会学到新东西。 - Mark Lakatafor(unsigned int i = length - 1; i < length; --i)
(我个人不偏好其中任何一个,只是为了完整性)。 - Aconcaguaunsigned int
,你可能会遇到一些逻辑错误。实际上,你通常并不需要unsigned int
的范围,使用int
更安全。这段代码与用例相关,如果你调用了某些向量元素,那原型就是int类型,但在C++中有许多现代化的方法来做到这一点,例如:for(const auto &v : vec) {} 或者使用迭代器,在某些计算中,如果没有减法/达到负数,应该使用无符号数(更好地解释了预期的值范围),有时候像这里发布的许多示例一样,实际上需要int,但事实是这完全取决于用例和情况,没有任何严格的规则适用于所有用例,强制执行一个规则会很愚蠢...
length
可能为负数,使用int
实际上更安全。如果使用unsigned int
,则length
也会被转换为unsigned int
。-1将变成类似于4294967295的值,会发生一些不好的事情。 - Brian Bilength
远小于INT_MAX
,那么使用int
和unsigned int
是等效的。我会选择打字更少的那个 :) - M.Mi
值达到最大值(如果i
是数组索引且i
为32位或更大,则这种情况可能性非常小),否则使用有符号或无符号并不重要。unsigned
存在的唯一理由是,如果您实际上需要最高有效位将正数范围扩展另一个因子2但不是更多。 - Mark Lakata