首页 > 解决方案 > 虽然循环超过限制

问题描述

while (('\0' != *str1) && ('\0' != *str2) &&
    (false == sensi) ? (std::toupper(*str1) == std::toupper(*str2)) : (*str1 == *str2)) {
    ++str1;
    ++str2;
}

此代码甚至在 NULL 终止符之后继续循环。

一定有一些非常明显的东西我在这里遗漏了,但我根本看不到它。

如果这两个代码之间的任何一个代码块&&被评估为假,它应该会中断,但它不会这样做,并且会继续解析字符串,甚至超过 NULL 终止符变成乱码。

标签: c++

解决方案


while (('\0' != *str1) && ('\0' != *str2) &&
    (false == sensi) ? (std::toupper(*str1) == std::toupper(*str2)) : (*str1 == *str2))

三元运算符?:的优先级低于几乎所有其他运算符,包括逻辑 AND &&。因此,&&首先应用 s,因此您在这里所说的是:

  • if str1is not at its NULterminator, && str2is not at its own,&&我们不区分大小写,
  • 然后?循环while字符串的当前字符不区分大小写,
  • else:循环while字符串的当前字符完全相等。

因此,如果字符串相等,或者至少越过它们的NUL终止符并进入未定义的行为区域,您将永远循环。


相反,您的意思是,我们将整个三元表达式包装在括号中,以覆盖其默认优先级,从而使语言将其评估为 的第三个条件&&

while ( *str1 != '\0' && *str2 != '\0' &&
        (!sensi ? std::toupper(*str1) == std::toupper(*str2) : *str1 == *str2) )

即循环while

  • str1不在其NUL终结者处,&&
  • str2不是自己的,&&
  • (?:字符串的当前字符以 .指定的方式相等sensi )

我建议在这里查看运算符优先级,不要过度使用多余的括号,也不要使用 Yoda 条件。此外,这个大的复合条件也许最好表示为一个单独的函数,将 2str秒作为输入并分别检查每个条件,以避免混淆长逻辑测试。


推荐阅读