简体   繁体   English

在C中while循环中切换语句

[英]Switch statement within while loop in C

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. 在while循环中有几个关于switch语句的帖子,除了它们都没有在C语言中完成的事实,至少从我看到的情况来看。 C++ can create boolean expressions, which I'm aware of, but not in C. I have a while loop that contains a switch control. C ++可以创建布尔表达式,我知道,但不是在C中。我有一个包含开关控件的while循环。 However, when I write break statements within my switch, it goes back to the beginning of the loop and makes my program run forever. 但是,当我在switch中编写break语句时,它会回到循环的开头并使我的程序永远运行。 Ignore the functions I use, for they work for sure. 忽略我使用的功能,因为它们确实有用。 I just need some clarification on my handling of the nesting. 我只需要澄清一下我对嵌套的处理方法。 Thanks! 谢谢!

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);
     }
}

break; will exit out of the nearest enclosing switch or loop. 将退出最近的封闭switch或循环。 To jump two levels, you'll have to use the dreaded goto , or reorganize so a return will accomplish the desired semantics. 要跳过两个级别,你必须使用可怕的goto ,或重新组织,以便return将完成所需的语义。

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 expression in 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);
        }
    }

You can have boolean expressions in C too. 您也可以在C中使用布尔表达式。 The C standard from 1999 has a stdbool.h header and a data type bool . 1999年的C标准有一个stdbool.h头和一个数据类型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方言中,例如Visual Studio 2012(!)中的方言,没有布尔数据类型,因此您需要使用简单的int:

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

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? 那么什么是0 == 0 ,如果不是布尔表达式? If you're referring to a variable of the type bool , make sure you #include <stdbool.h> . 如果你指的是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. 但是,当我在switch中编写break语句时,它会回到循环的开头并使我的程序永远运行。 Ignore the functions I use, for they work for sure. 忽略我使用的功能,因为它们确实有用。 I just need some clarification on my handling of the nesting. 我只需要澄清一下我对嵌套的处理方法。 Thanks! 谢谢!

No. It doesn't go back to the beginning of the loop. 不。它不会回到循环的开头。 Execution continues from the end of the switch statement (immediately after the switch es closing brace, } ). 执行从switch语句的结尾继续执行(紧接在switch es closing brace之后, } )。 In your circumstance, this is functionally identical to going back to the beginning of the 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 new variables, 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, return from main when you want to exit, or call exit(0); 或者,当您想要退出时,从main return ,或者调用exit(0); from other functions. 来自其他功能。 This isn't all that helpful if you want to run extra cleanup/output code. 如果您想运行额外的清理/输出代码,这并不是很有用。

In this scenario, the switch control structure isn't really any better than a chain of if / else if / else branches. 在这种情况下, switch控制结构实际上并不比if / else if / else分支链好。 If you were to use the if / else if / else branches, you'd be able to break; 如果你要使用if / else if / else分支,你就可以break; out of the loop more easily. 更容易摆脱循环。 I'd use a switch control structure when I want execution to flow through into other cases. 当我希望执行流入其他情况时,我会使用switch控制结构。

As another option, you could use a goto expression to break out of the loop to a label outside of main. 作为另一种选择,您可以使用goto表达式将循环跳出到main之外的标签。 This would be best when there are multiple possible exit points from the loop, such as handling and cleanup following allocation errors. 当循环中有多个可能的退出点时,例如处理和清除分配错误后,这将是最好的。

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循环

Your break only leaves the switch statement, then continues on in the 你的休息只留下switch语句,然后继续

while(1)

loop forever. 永远循环。

use exit(0); 使用exit(0);
wherever you want to exit. 无论你想要退出的地方。

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: return statement. 从while循环中出来的其他方法可能是使用: return语句。 But this will also exit the current function. 但这也将退出当前的功能。

Appropriate solution might be to use goto label; 适当的解决方案可能是使用goto label; inside the switch and then use label: statement; 在开关内部然后使用label: statement; outside the while loop. 在while循环之外。

Eg: 例如:

while(1){
  switch(x){

   case 0:goto label;

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM