C++ 断言无符号int a确实为正不';不行?
我想乘以两个数字,我知道我的数字总是正的,那么:C++ 断言无符号int a确实为正不';不行?,c++,assert,unsigned,unsigned-integer,C++,Assert,Unsigned,Unsigned Integer,我想乘以两个数字,我知道我的数字总是正的,那么: unsigned int mulPositiveNumbers(unsigned int a ,unsigned int b) { assert(a > 0); assert(b > 0); return (a*b); } 现在,我用assert告诉自己“给定的数字总是正的” 但当我跑步时: int main() { unsigned int res = mulPositiveNumbers(-4,
unsigned int mulPositiveNumbers(unsigned int a ,unsigned int b)
{
assert(a > 0);
assert(b > 0);
return (a*b);
}
现在,我用assert告诉自己“给定的数字总是正的”
但当我跑步时:
int main()
{
unsigned int res = mulPositiveNumbers(-4,3);
// more stuff goes here
}
代码没有失败,即使我使用的是负数。为什么? 您没有使用负数,它被转换为
无符号int
,因为这是函数的参数
只有当数字为
0
时,断言才会失败。您的类型“unsigned int”将隐式-4转换为无符号等效值请尝试以下操作:
(unsigned int a ,unsigned int b)
因为
a
和b
是无符号的,所以它们永远不能是负数。断言失败的唯一方法是其中一个为0
当您使用带符号int作为参数调用函数时,在函数执行之前(因此在检查断言之前),它将被转换为无符号int。将负整数转换为无符号整数将产生一个正整数,因为正如我所说,没有负无符号整数。因为-4被解释为无符号(32位)整数是
4294967291
,这肯定是正的
以下内容应该按照您的意愿工作
unsigned int mulPositiveNumbers(int a, int b)
{
assert(a > 0); // Fail for (-4, 3)
assert(b > 0);
return (a*b);
}
当您执行此操作时,还应该断言乘法的结果是否会溢出,或者选择一个更大的返回类型(例如)它将其转换为无符号等价物。好的,那么您的意思是
assert()
在这种情况下是没有必要的?@ron它们必须确保a
和b
不是0(假设a
和b
不能是0-如果允许它们是0,您的断言实际上是错误的)。如果这不是一个问题,它们就没有作用。您可能希望在以有符号整数作为参数调用函数的任何地方添加断言,以确保没有将负整数转换为无符号整数(因为如果发生这种情况,可能在某个地方出错,转换将隐藏错误)。请注意,将unsigned int
更改为int
会将可能值的范围减少一半。long
不一定大于int
——它的排名较高,但大小可能相同。它的大小通常是相同的,例如在32位linux和所有Windows上。@SteveJessop很好的一点——我最近做了太多的C#。更新。