在很多代码示例,源代码,库等中。我看到使用int时,unsigned int
会更有意义。
我在for
循环中看到的很多地方。见下面的例子:
for(int i = 0; i < length; i++)
{
// Do Stuff
}
为什么你会使用int
而不是unsigned int
?这只是懒惰 - 人们不能打扰unsigned
?
答案 0 :(得分:22)
使用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
引入了这类错误的可能性,并没有任何好处。
答案 1 :(得分:7)
它通常是懒惰或缺乏理解。
当值不应为负数时,我会使用unsigned int。这也用于指定正确值应该是什么的文档目的。
恕我直言,断言使用它更安全&#34; int&#34;比&#34; unsigned int&#34;是完全错误的,也是一种糟糕的编程习惯。
如果您使用过Ada或Pascal,您可能习惯于使用更安全的方法来指定值的特定范围(例如,只能是1,2,3,4,5的整数)。 / p>
答案 2 :(得分:3)
如果length
也是int
,那么你应该使用相同的整数类型,否则在比较语句中混合有符号和无符号类型时会发生奇怪的事情。大多数编译器会给你一个警告。
你可以继续问,为什么要length
签名?嗯,这可能是历史性的。
另外,如果您决定反转循环,即
for(int i=length-1;i>=0 ;i--)
{
// do stuff
}
如果使用无符号整数,则逻辑会中断。
答案 3 :(得分:3)
我选择在编程时尽可能明确。也就是说,如果我打算使用其值始终为正的变量,则使用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
的事情,但这似乎更像是使用有符号整数而不是更明确并使用无符号开头的kludge。
答案 4 :(得分:2)
我认为最重要的原因是如果选择unsigned int
,您可能会遇到一些逻辑错误。事实上,您通常不需要unsigned int
的范围,使用int
更安全。
答案 5 :(得分:0)
这个小代码与用例相关,如果您调用某些向量元素,则原型为int,但是有很多现代方法可以在c ++中实现。 for(const auto&v:vec){}或迭代器,在某种程度上可以计算,如果不减去/达到负数,您可以并且应该使用无符号(更好地解释期望的值范围),有时这里发布的许多示例实际上向您展示了需要int,但事实是,这全都与用例和情况有关,没有一个严格的规则适用于所有用例,将其强加于人有点愚蠢……