C/C++ use of int or unsigned int
C/C++ use of int or unsigned int
在大量的代码示例、源代码、库等。在我看来,当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,但事实是这完全取决于用例和情况,没有一个严格的规则适用于所有用例,强制使用一个会有点愚蠢…
- 为什么在全局范围内使用"extern int a"似乎不行?
- int(c) 和 c-'0' 之间的区别。C++
- 从"int*"强制转换为"unsigned int"会丢失精度错误
- 为什么野牛仍在使用"int yylex(void)",却找不到"int yylex(YYS
- 有符号的int和int-有没有一种方法可以在C++中区分它们
- 请解释这句话(cout<<1+int((a<b)^((b-a)&1) )<<endl
- 是否可以从int转换为enum类类型
- 不能在初始值设定项列表中将非常量表达式从类型 'int' 缩小到'unsigned long long'
- 向量 <int> a {N, 0} 和 int arr a[N] = {0} 的时间复杂度有什么区别
- 'short int'持有的值溢出,但"自动"不会溢出?
- 如何在C++中将一个无符号的 int 转换为两个无符号的短裤?
- 调用'begin(int [n])'没有匹配函数
- 瓦尔格林德:数学函数"Conditional jump or move depends on uninitialised value(s)"
- 没有显式声明的int[]中的foreach
- 在c++中访问int到类对象的映射时出错
- typedef int* intptr OR typedef int *intptr;
- "Called object 'int' is not a function or a function pointer"错误
- int和char的逐位OR
- Send() and recv() double or int
- C/C++ use of int or unsigned int