【问题标题】:For Loop is not iterating for a third time? (C++)For Loop 不是第三次迭代? (C++)
【发布时间】:2022-01-17 17:15:28
【问题描述】:

问题:为什么我的 for 循环没有第三次迭代?

我注意到了:在下面的 for 循环语句中,删除 if-else 语句允许我打印 0-2 和 "1" 的 i 3 次。

for (size_t i {0}; i < user_input.length(); ++i) {
        
        cout << i << endl;
        cout << user_input.length() << endl;
        
        string the_spaces;
        string the_line;

        for (size_t b {i}; b < (user_input.length() - 1); ++b) {
            the_spaces += " ";
        }

        for (size_t k {0}, y {i+1}; k < y; ++k) {
            the_line += user_input[k];
        }
        
        if (i >= 1) {
            cout << "Bob";
            for (size_t z {i - 1}; z >= 0; --z) {
                the_line += user_input[z];
            }
        }
        else {
            cout << "Beb" << endl;
        }
        
        cout << "1" << endl;
            
    } 

Output:

0                   // i
3                   // the user_input.length
Beb                 // output from if-else
1                   // 1 printed at the end of the for loop expression
1                   // i (2nd iteration)
3                   // the user input.length 

代码到此结束...既不打印 Beb 或 Bob,也不打印 cout 在第 2 次和第 3 次迭代中的 "1"。

【问题讨论】:

  • for (size_t z {i - 1}; z &gt;= 0; --z) 是无限循环。
  • 这应该是学习如何调试你的程序的最佳时机。例如,使用 调试器,您可以在监视变量及其值的同时逐句执行代码。
  • 甚至不应该需要调试器 - 只需打开(所有)编译器警告:任何理智的人都会警告您 z &gt;= 0 总是正确的。

标签: c++ for-loop if-statement


【解决方案1】:

对已经给出的答案的补充:另一种符合 C++ 标准且高度可移植的签名类型适用于 zstd::ptrdiff_t。 (类似于POSIX的ssize_t。)

(引用标准:“std::ptrdiff_t 用于指针算术和数组索引,如果可能有负值。”)

【讨论】:

    【解决方案2】:

    在for循环中:

    for (size_t z {i - 1}; z >= 0; --z) {
        the_line += user_input[z];
    }
    

    因为size_t 永远不会是负数,所以z &gt;= 0 永远是正确的。所以这是一个无限循环。

    您可以对其进行类型转换:

    for (long long z {static_cast<long long>(i - 1)}; z >= 0; --z) {
        the_line += user_input[z];
    }
    

    或者如果你不想对它进行类型转换,你可以使用这种相当奇怪的方式:

    for (size_t z{i}; z-- > 0; )
        the_line += user_input[z];
    }
    

    【讨论】:

    • 感谢修复。 “相当奇怪的方式”是我的做法,虽然我喜欢写 z --&gt; 0,因为我觉得它更好地表达了成语。
    • @Bathsheba 我也会使用我相当奇怪的方式。有趣的是,您将其称为幻灯片运算符,而我将其称为 downto 运算符。也许它在 C++ 标准之间有所不同
    • 如果我们认为 C++ 标准愿意提及它,听的人会感到震惊。当然,它根本不是真正的操作员。我在大学的 C 天开始使用它。
    • @Bathsheba 这看起来有点奇怪。大多数合理的编码约定/设计规则规定后缀运算符应直接出现在变量之后,并且比较运算符与其操作数之间应有空格。 “看起来很有趣”并不是打破既定惯例的好理由。
    • @Alderath:是的,第一次检查时确实看起来很奇怪。但是请记住,无符号减法没有关闭,-- 对无符号类型来说是一件奇怪的事情。是的,我想这取决于时尚。
    【解决方案3】:

    z &gt;= 0 始终是 true,因为 zunsigned 类型。

    您的程序因此循环。虽然还有其他解决方案,但使用long long 而不是std::size_t 作为循环索引可能是最简单的。


    如果user_input 为空,b &lt; (user_input.length() - 1) 也会有问题。使用

    b + 1 < user_input.length()
    

    改为。

    【讨论】:

    • 请允许我添加一个建议:std::ptrdiff_t 也适用于 z。 (标准规定:“std::ptrdiff_t 用于指针算术和数组索引,如果可能有负值。”这完全符合这个用例)。
    • @ChristianHalaszovich:是的,这还不错。为什么不提交答案?当有可供选择的选项时,堆栈溢出效果最佳。我想虽然我更喜欢基于std::make_signed 的东西。我个人在使用无符号类型倒数时使用--&gt;(滑动运算符),因此根本不会弄乱类型,但它已经过时了。
    猜你喜欢
    • 2012-10-20
    • 1970-01-01
    • 2016-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多