为什么“if (unsigned int == string::npos)”可以为真?

时间:2021-01-20 21:24:48

标签: c++

首先让我说:如果有人对此进行了解释,我很抱歉,我尝试阅读它并寻找答案,但没有找到回答这个特定问题的答案。

所以我正在用 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”是一个无符号整数,我认为比较“where == string::npos”是个坏主意,因为string::npos是用-1初始化的,而无符号整数不能等于- 1.但是如果函数没有找到任何东西并且它返回 string::npos 条件可以为真,程序会识别“unsigned int where”是 string::npos,但是当我尝试打印“where”时,它会打印out 为 unsigned int 可以容纳的最大数。

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

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

2 个答案:

答案 0 :(得分:3)

如果您阅读the documentation

<块引用>

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

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

答案 1 :(得分:1)

string::npos 是一个很大的正数。

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

  • 返回 string::size_type 而不是 int,或者:
  • 在第一个代码中返回一些其他失败标记,例如 -1

就您现在拥有的方式而言,当“调整后的”值适合返回类型恰好与有效返回值相同时,总是会发生冲突。

尽管 npos 可能在实现标头中用 -1 初始化,但这并不意味着它的值为 -1。初始值设定项转换为被初始化对象的类型,即 string::size_type,保证是无符号类型。这种转换的结果是一个很大的正值。


注意。如果在长度超过 UINT_MAX 个字符的字符串上调用您的代码,您的代码会很糟糕,因为 i 循环永远不会结束。 i 也应该是 string::size_type 而不是 int;和类似的注意事项适用于 startPos 参数。