为什么"if (unsigned int == string::npos )"可以是真的?



让我开始说:我很抱歉,如果这是解释,我试着阅读它并寻找答案,但我没有找到一个回答这个特定的问题。

所以我正在用c++编写初学者级别的代码,我写了一个非常简单的函数,返回下一个找到的字符的索引,而不是空格。它的灵感来自于方法string.find()。如果函数没有找到任何内容,则返回string::npos.

int findChar (const string &line, const int startPos){
for (unsigned int i= startPos; i < line.length(); i++){
if ( line[i] != ' ') return i;
}
return string::npos;
}

现在,因为我正在处理字符串和索引,我想使用unsigned int。

unsigned int where;
where = findChar(line, 0);

因为"where"是一个unsigned int,我认为比较"where == string::npos"这是个坏主意,因为string::npos初始化为-1,而unsigned int不能等于-1。但是如果函数没有找到任何东西,并且返回string::npos条件可能为真,程序就会识别出&;unsigned int where&;是字符串::npos,但是当我尝试打印"where"输出时,输出unsigned int所能容纳的最大数值。

所以我的问题是为什么,或者如何,程序可以识别unsigned int等于string::npos,即使技术上string::npos初始化值为-1。

我正在努力学习,所以如果你能给我指一些同样回答这个问题的阅读材料,我将不胜感激。

如果你阅读了文档:

虽然定义使用了-1,但size_type是一个无符号整数类型,由于有符号到无符号的隐式转换,npos的值是它所能容纳的最大正值。这是一种可移植的方式来指定任何unsigned类型的最大值。

注:std::string::npossize_t类型。使用其他任何东西都可能是未定义的行为,不建议.

string::npos是一个大正数。

为了避免这些问题,你的函数的返回类型应该与你返回的值的类型匹配,例如:

  • 返回string::size_type而不是int,或者:
  • 返回一些其他的失败哨兵,如第一个代码中的-1

你现在的方式,总是有冲突,当"调整"适合返回类型的值恰好与有效的返回值相同。

虽然npos可能在实现头文件中用-1初始化,但这并不意味着它的值是-1。初始化器被转换为被初始化对象的类型,即string::size_type,保证为无符号类型。转换的结果是一个大的正值。


NB。如果在超过UINT_MAX字符的字符串上调用您的代码将会严重中断,因为i循环永远不会结束。i也应该是string::size_type而不是int;类似的考虑也适用于startPos参数。

最新更新