如何防止这种无限循环

Posted

技术标签:

【中文标题】如何防止这种无限循环【英文标题】:How do I prevent this infinite loop 【发布时间】:2020-02-18 01:07:20 【问题描述】:

当我运行以下代码时,有时它会成功退出,有时它会在highestNum等于255时进入无限循环。我知道这是因为当255递增并变为0时发生翻转。我明白为什么会这样正在发生,但我想就停止这种情况提出建议。我是否应该在最后放置一个 if 语句来检查 i 是否等于最大数,然后在最后中断?这似乎是一种糟糕的风格,如果我增加变量的大小,很容易忘记修复。

    // delete all the files
    for (unsigned char i = 0; i <= highestNum; i++)
        rc = snprintf(formatString, sizeof(formatString), "x%u", i);
        if (rc < 0)
            perror("snprintf in delete");
        
        rc = unlinkat(directoryFD, formatString, 0);
        if (rc == 0)
            printf("file unlinked\n");
        
    

【问题讨论】:

您需要为工作选择正确的变量。如果您知道您永远不会拥有highestNum >= 255,那么当前的实现就可以了。但是,如果您可以拥有 highestNum >= 255,那么您应该选择不同的类型。 使用unsigned short 而不是unsigned char 代表i 【参考方案1】:

使用 unsigned int 类型代替 unsigned char 类型。:) 否则,当 i 等于类型的最大值 255 (UCHAR_MAX is equal to 255) 时,i 递增后的下一个值将再次为 0,您将获得无限循环。

因此,变量highestNum 的任何值等于或大于UCHAR_MAX 都会导致无限循环。

【讨论】:

【参考方案2】:

您可以使用更广泛的类型(例如unsigned int)来执行此操作,只需最少的代码更改。另一种选择是使用不同的循环变体,例如do..while:

int highestNum = 255;

    unsigned char i = 0;
    do 
        printf("%u\n", i);
        ++i;
     while (i <= highestNum && i != 0);

这与您的for 循环具有相似的作用域,因为i 不会“转义”它声明的块,并且针对零检查i 会捕获环绕的情况(在for 循环,因为它在每次迭代的开始而不是结束时检查条件。

请注意,没有检查以确保 highestNumber 为零或更多,因此至少 一个 文件将始终被删除。如果您希望能够不指定文件(例如,如果要删除 no 个文件,则将 highestNumber 设置为 -1),您可以添加一个简单的预检查:

int highestNum = 255;
if (highestNumber >= 0) 
    unsigned char i = 0;
    do 
        printf("%u\n", i);
        ++i;
     while (i <= highestNum && i != 0);

【讨论】:

【参考方案3】:

避免这种情况的一种方法是将i 声明为int,然后在使用它的循环中将其转换为char

for (unsigned int i = 0; i <= highestNum; i++)
    rc = snprintf(formatString, sizeof(formatString), "x%u", (unsigned char) i);
    if (rc < 0)
        perror("snprintf in delete");
    
    rc = unlinkat(directoryFD, formatString, 0);
    if (rc == 0)
        printf("file unlinked\n");
    

【讨论】:

以上是关于如何防止这种无限循环的主要内容,如果未能解决你的问题,请参考以下文章

为啥错误:重新渲染太多。 React 限制了渲染的数量以防止无限循环。?

componentDidUpdate 错误是 React 限制嵌套更新的数量以防止无限循环如何解决此问题

从管道读取的无限循环线程进入 timed_waiting

防止 toString() 中无限递归的最有效方法?

我如何摆脱这种无限循环?

太多的重新渲染。 React 限制了渲染的数量以防止无限循环。?