如何解决c和c ++中的隐式转换问题
我正在做以下事情:
int num_of_pairs(std::vector<char>& str)
{
for(int i = 0; i < str.size() - 1; i++)
{
if(str[i] == str[i + 1])
# Do something
}
}
但是当我传递一个长度为0的空向量时,for循环仍然执行并抛出索引错误。 vector.size()返回一个size_t,它在我的编译器上是无符号的int64,我认为编译器将arr.size()-1作为size_t进行计算,然后转换为int以检查条件,因为当arr.size()为0时,则为arr .size()-1变成了一个非常大的数字,可能是2 ^ 64-1。
当我做同样的事情
int n = 50000;
unsigned int a = n*(n + 1);
这给我带来了垃圾,因为50000 * 50000变为2.5 Billon,这对于有符号整数是溢出的,但是无符号整数可以存储它。
我有两个问题,
- 我在想正确吗(我想是的,但是我想确认,因为我不是netwon或einstien)
- 如何避免这种情况
解决方法
成员函数std::vector<char>::size_type
具有的类型size
是无符号整数类型。所以这个表情
str.size() - 1
如果由于常规算术转换而使str.size()
等于0
,则产生无符号整数类型的最大值。
在这种情况下
i < str.size() - 1
没有强制转换为类型int
。由于相同的常用算术转换,再次将左操作数隐式转换为类型std::vector<char>::size_type
。
因此,在for循环之前,应检查str.size()
是否等于0
。
或者您可以像这样重写循环
for( std::decay_t<decltype( str )>::size_type i = 1; i < str.size(); i++)
{
if(str[i] == str[i - 1])
# Do something
}
关于此代码段
int n = 50000;
unsigned int a = n*(n + 1);
然后在表达式n*(n + 1)
中,类型int
发生了溢出。
(1)您几乎是正确的。当arr.size()为0时,arr.size()-1变为非常大的数字2 ^ 64-1,如果size_t是64位数字,但是变量i强制转换为std :: vector :: size_type(通常size_t)检查条件。
另一件事发生在这里
int n = 50000;
unsigned int a = n*(n + 1);
在这里,如果int
是32位的,则n*(n + 1)
表达式的执行会导致溢出;没有强制转换为unsigned int。对无符号int的强制转换适用于n*(n + 1)
表达式的结果,该表达式未由标准指定,但应在编译器文档中定义。
(2)有很多方法可以重写此功能:
for(size_t i = 1; i < str.size(); i++)
{
if ( str[i - 1] == str[i] )
// Do something
}
或
int num_of_pairs(std::vector<char>& str)
{
if ( str.size() < 2 )
return 0;
for(size_t i = 0; i < str.size() - 1; i++)
{
if(str[i] == str[i + 1])
# Do something
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。