为什么以下代码进入无限循环?

时间:2012-12-15 04:00:37

标签: c for-loop infinite-loop goto

请考虑以下代码:

const char *s = "a   b    c  d !";
const char *p = s;

top:for(; *p; p++) {
    switch(*p) {
    case 0x20: 
    case '\n': 
        goto top;
    default: 
        putchar(*p);
    }
}

有人可以解释为什么它进入无限循环而不是在*pNULL时停止?我想到了以下内容:当*p0x20\n再次进入循环的开头时,因为它会测试条件并评估表达式p++。所以,我没有看到它无限循环的原因,或者我真的不知道goto语句和labels如何在C编程语言中工作。

3 个答案:

答案 0 :(得分:5)

当您goto top时,p++未执行,因为for循环从头开始。然后再次goto top。然后再说一遍。然后再说一遍。永远。

如果您希望增量有效,请使用continue代替goto。或者,更好的是,做一些更清楚的事情:

for(p = s; *p != '\0'; p++) {
    switch(*p) {
    case 0x20:
    case '\n':
        // Do nothing.
        break;

    default: 
        putchar(*p);
    }
}

哦,顺便说一句,避免像瘟疫那样的goto陈述。除非你以自动方式生成C代码并且它不应该是人类可读的,否则goto几乎不是一个好主意。

答案 1 :(得分:1)

这样做

const char *s = "a   b    c  d !";
const char *p = s;

 for(; *p; p++) {
    switch(*p) {
    case 0x20: case '\n': continue;
    default: putchar(*p);
    }
  }

原因是,您的代码甚至没有完成一次迭代,因此p ++永远不会执行。当您继续而不是使用标签时,它会计入一次完整的迭代。

答案 2 :(得分:0)

const char *s = "a   b    c  d !";
const char *p = s;

top:
for(; *p; p++) {
    switch(*p) {
    case 0x20: 
    case '\n': 
        p ++;
        goto top;
    default: 
        putchar(*p);
    }
}

您必须在p ++;之前使用goto top;,因为转到top:表示您正在重新启动循环。