C语言 C 中 while 循环中的 Switch 语句

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16117322/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 06:06:32  来源:igfitidea点击:

Switch statement within while loop in C

cloopswhile-loopswitch-statementinfinite-loop

提问by umarqattan

There are several postings concerning switch statements within while loops, except for the fact that none of them are done in C, at least from what I've seen. C++ can create boolean expressions, which I'm aware of, but not in C. I have a while loop that contains a switch control. However, when I write break statements within my switch, it goes back to the beginning of the loop and makes my program run forever. Ignore the functions I use, for they work for sure. I just need some clarification on my handling of the nesting. Thanks!

有几篇关于 while 循环中的 switch 语句的帖子,除了它们都不是在 C 中完成的,至少从我所看到的情况来看。C++ 可以创建布尔表达式,我知道,但不是在 C 中。我有一个包含开关控件的 while 循环。但是,当我在 switch 中编写 break 语句时,它会回到循环的开头并使我的程序永远运行。忽略我使用的功能,因为它们确实有效。我只需要澄清一下我对嵌套的处理。谢谢!

Here is my main.c:

while(1)
{
    printf("0) Exit\n1) List Tasks\n2) Add Task\n");                                            
    printf("3)Delete Task\n4) Add Task From File\n");                                           
    printf("What would you like to do?\n");
    fgets(buf1, 50, stdin);                                                                     
    p = atoi(buf1);
    switch(p)
    {
          case 0: 
            break;
          case 1: 
            printTaskList(pTaskList);
            break;
          case 2:
            printf("Enter task name: ");
            fgets(buf2,100,stdin);
            printf("Enter task priority: ");
            fgets(buf3,100,stdin);
            printf("Enter task start date: ");
            fgets(buf4,50,stdin);
            pTask = makeTask(buf2,buf4,buf3);
            addTaskToEnd(pTaskList,pTask);
            break;
          case 3:
            printTaskList(pTaskList);
            printf("What task would you like to delete? ");
            fgets(buf6,50,stdin);
            taskNum = atoi(buf6);
            removeTask(pTaskList,taskNum);
            break;
          case 4:
            printf("Enter the filename ");
            fgets(buf7,50,stdin);
            break;
          default:
            printf("ERROR: %d: Incorrect menu option\n", p);
     }
}

回答by luser droog

break;will exit out of the nearest enclosing switchor loop. To jump two levels, you'll have to use the dreaded goto, or reorganize so a returnwill accomplish the desired semantics.

break;将退出最近的封闭switch或循环。要跳转两个级别,您必须使用 dreadedgoto或重新组织,以便 areturn完成所需的语义。

while(1) {
    switch(x) {
    case 0: goto EndWhile;
    }
}
EndWhile: ;

Or

或者

void loop() {
    while(1) {
        switch(x) {
        case 0: return;
        }
    }
}
//...
loop();
//...

You can totally use a Boolean expressionin C. Just use an int.

您完全可以在 C 中使用布尔表达式。只需使用int.

int quit = 0;
while(!quit) {
    switch(x) {
    case 0: quit = 1; break;
    }
}

C also has a boolean data type, if you really want it.

C 也有一个布尔数据类型,如果你真的想要的话。

#include <stdbool.h>

bool quit = false;
while(!quit) {
    switch(x) {
    case 0: quit = true; break;
    }
}

And one more option, for the totally insane.

还有一种选择,对于完全疯狂的人。

#include <setjmp.h>

jmp_buf jbuf;
if (!setjmp(jbuf))
    while(1) {
        switch(x) {
        case 0: longjmp(jbuf, 1);
        }
    }

回答by Thomas Padron-McCarthy

You can have boolean expressions in C too. The C standard from 1999 has a stdbool.hheader and a data type bool. In older C dialects, such as the one in Visual Studio 2012 (!), there is no boolean data type, so you need to use plain ints instead:

你也可以在 C 中使用布尔表达式。1999 年的 C 标准有一个stdbool.h头文件和一个数据类型bool。在较旧的 C 方言中,例如 Visual Studio 2012 (!) 中的方言,没有布尔数据类型,因此您需要使用普通整数:

int keep_looping = 1;
while (keep_looping) {
    ....
    if (....)
        keep_looping = 0;
}

回答by autistic

C++ can create boolean expressions, which I'm aware of, but not in C.

C++ 可以创建布尔表达式,我知道,但在 C 中不能。

Oh? So what is 0 == 0, if not a boolean expression? If you're referring to a variable of the type bool, make sure you #include <stdbool.h>.

哦?那么什么是0 == 0,如果不是布尔表达式呢?如果您指的是 类型的变量bool,请确保您是#include <stdbool.h>.

However, when I write break statements within my switch, it goes back to the beginning of the loop and makes my program run forever. Ignore the functions I use, for they work for sure. I just need some clarification on my handling of the nesting. Thanks!

但是,当我在 switch 中编写 break 语句时,它会回到循环的开头并使我的程序永远运行。忽略我使用的功能,因为它们确实有效。我只需要澄清一下我对嵌套的处理。谢谢!

No. It doesn't go back to the beginning of the loop. Execution continues from the end of the switch statement (immediately after the switches closing brace, }). In your circumstance, this is functionally identical to going back to the beginning of the loop.

不。它不会回到循环的开头。从 switch 语句的末尾继续执行(紧跟在switches 右大括号之后})。在您的情况下,这在功能上与返回到 loop 的开头相同。

There are a few of options available to you. Others are suggesting using a sole variable to control your loop. This would be a good idea, but they're suggesting using newvariables, despite the fact that the variable already exists in your logic. If you want to solve your problem this way, consider:

有几个选项可供您使用。其他人建议使用唯一变量来控制您的循环。这将是一个好主意,但他们建议使用变量,尽管该变量已存在于您的逻辑中。如果您想以这种方式解决您的问题,请考虑:

do {
    /* ... */
} while (p != 0);

Alternatively, returnfrom main when you want to exit, or call exit(0);from other functions. This isn't all that helpful if you want to run extra cleanup/output code.

或者,return从 main 退出时,或exit(0);从其他函数调用。如果您想运行额外的清理/输出代码,这并不是很有帮助。

In this scenario, the switchcontrol structure isn't really any better than a chain of if/else if/elsebranches. If you were to use the if/else if/elsebranches, you'd be able to break;out of the loop more easily. I'd use a switchcontrol structure when I want execution to flow through into other cases.

在这种情况下,switch控制结构是不是真的任何优于链if/ else if/else分支。如果你使用if/ else if/else分支,你可以break;退出循环更容易。switch当我希望执行流到其他情况时,我会使用控制结构。

As another option, you could use a gotoexpression to break out of the loop to a label outside of main. This would be best when there are multiple possible exit points from the loop, such as handling and cleanup following allocation errors.

作为另一种选择,您可以使用goto表达式跳出循环到 main 之外的标签。当循环有多个可能的退出点时,这将是最好的,例如分配错误后的处理和清理。

回答by abe312

use exit(0);
wherever you want to exit.

使用退出(0);
无论你想退出。

In this partcular case you have to put the condition in the while loop parameter

In this partcular case you have to put the condition in the while loop parameter

other ways to come out from the while loop might be to use: returnstatement. But this will also exit the current function.

从while循环中出来的其他方法可能是使用: return语句。但这也将退出当前功能。

Appropriate solution might be to use goto label;inside the switch and then use label: statement;outside the while loop.

适当的解决方案可能是goto label;在 switch 内部使用,然后label: statement;在 while 循环外部使用。

Eg:

例如:

while(1){
  switch(x){

   case 0:goto label;

   default:break;
   }
}
label:
printf("out of while loop");

回答by Jensd

You never exit the loop. The break will just break your switch. You should replace

你永远不会退出循环。休息只会破坏你的开关。你应该更换

while(1)

with something else that implies that the while-loop should be exited

还有其他暗示应该退出while循环的东西

回答by koljaTM

Your break only leaves the switch statement, then continues on in the

你的 break 只离开 switch 语句,然后继续在

while(1)

loop forever.

永远循环。