首页 > 解决方案 > For循环遍历数组导致无限循环

问题描述

我有一段代码应该在按下回车键时刷新一个字符数组,只有代码无限循环,我不知道为什么。

有一个字符数组,每次按下一个键时都会获取一个新字符。当检测到回车键时,将执行以下代码以在屏幕上生成新行之前用 '\0' 字符刷新字符数组:

int main()
{
    char i;
    char c;
    char buffer[80];
    i = 0;
    c = 0;

        while (c = bgetchar())
        {
            if (c == 13)
            {
                for (i = i; i >= 0; i--)
                {
                    buffer[i] = '\0';
                }
            }
            else
            {
                buffer[i] = c;
                i++;
            }
        }
}

每次按下一个字符(除了输入(ASCII 13))时,i 在主循环中都会增加。该字符也被添加到缓冲区[]。该代码未在此处显示,但我可以重现它。不用说,即使该代码不正确地增加了 i,循环也应该在 i 达到 0 时结束(并且考虑到减量,我应该在某个点达到 0)。

所以理论上,在按下回车键时,如果行上有 5 个字符(并且没有退格),缓冲区 [] 元素 0-4 将具有字符,并且 i 将等于 5。代码中的循环应该用 '\0' 字符替换元素 5 到 0。诚然,从元素 5 开始是不必要的,但它不应该导致我一直在经历的行为。

这种行为是循环无休止地运行。现在我已经能够通过使用我的 putchar 函数在每次循环运行时打印一个字符来验证这一点。现在我想我可以编写另一个函数来打印 i 的值,我可能会得到我的问题的答案。此外,对于它的价值,当我将这个循环变成等效的“while”循环时,就会发生无限循环。

我只是想确保这里没有明显的东西会导致无限循环行为。对不起,如果这是一个愚蠢的问题。谢谢你的帮助。该程序以 16 位实模式作为原始二进制文件运行。我正在从 bcc 编译到 as86 到最终的二进制文件。

编辑:在进行更多调试后,我确认 i 以正确的正值进入循环(基于数组中的字符数,例如,如果 7 个字符,则 i = 7)。然而,在 for 循环中,i 在 -1 和 -2 的值之间无限交替。由于基于 i 的输入值(或基于循环的条件)没有任何意义,这是否有可能是某种内存或寄存器问题?

最终编辑:问题似乎是 >= 导致 i 变为负数的条件。由于某种原因,即使 for 循环中的条件检查是否为负 i,这也会导致无限循环。感谢所有的帮助。

标签: carraysfor-loopcharacterbcc-compiler

解决方案


由于某种原因,即使 for 循环中的条件检查是否为负 i,这也会导致无限循环。

“for循环检查中的条件”为真,但在需要的任何地方都没有检查该条件。


至少有一个问题:尝试 未定义buffer[-1] = c;的行为(UB)——其中可能包含无限循环。

后面 (c == 13)的输入不是 13 时,代码会尝试这个 UB。

    while (c = bgetchar()) {
      if (c == 13) {
        for (i = i; i >= 0; i--) {
          buffer[i] = '\0';
        }
        // now i == -1;
      } else {
        // No protection here that `i` is on the 0..79 range
        buffer[i] = c;
        i++;
      }
    }

for (i = i; i >= 0; i--)值得怀疑,因为它的第一个buffer[i] = '\0';是在其他方面没有设置的东西buffer[i] = c; i++;

我怀疑OP需要

        // for (i = i; i >= 0; i--) {
        for (i = i; i > 0; ) {
          // buffer[i] = '\0';
          buffer[--i] = '\0';
        }

char i;是不寻常的。我希望有一个固定的签名类型,而不是一个char可能有符号或无符号的类型。也许unsigned char i(在上述修复之后)或size_t i;数组索引的惯用语。


推荐阅读