2013-04-20 57 views
5

在while循環中有幾個關於switch語句的帖子,除了它們都沒有在C語言中完成的事情,至少從我所見過的事實中除外。 C++可以創建布爾表達式,我知道這些布爾表達式,但不包含在C中。我有一個包含開關控件的while循環。但是,當我在交換機中寫入break語句時,它會返回到循環的開頭,並使我的程序永遠運行。忽略我使用的功能,因爲它們確實有效。我只需要對我的嵌套處理進行一些說明。謝謝!C語言while循環中的switch語句

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

你break語句用來跳過開關條款的休息,這意味着你在切換後的行dump出來。一個解決嵌套作用域的通用解決方案是將代碼移入函數中,並使用return而不是break。 – 7stud 2013-04-20 06:16:03

+0

確定你想要在開關體內的while循環中分出的點,設置一個表示這個的標誌,並且讓'while(expression)'評估標誌爲break狀態(即'while(true)'變成'而(stay_in_while)'和'已經通過stay_in_while'開關代碼清除你想打破。 – WhozCraig 2013-04-20 06:16:34

+1

你錯了,C具有布爾表達式和數據類型。它具有內置式'_Bool'如果包含''還有'bool','false'和'true'。 – 2013-04-20 06:31:05

回答

13

break;將退出直接封閉switch或環出。要跳轉兩級,您必須使用可怕的goto,或重新組織,以便return能完成所需的語義。

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

或者

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

你完全可以使用布爾表達式在C.只需使用一個int

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

如果你真的想要,C也有一個布爾數據類型。

#include <stdbool.h> 

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

還有一個選項,對於完全瘋了。

#include <setjmp.h> 

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

你說得很清楚!非常感謝!你的代碼解決了我的無限循環錯誤,以及你們所有人。我意識到我必須標記我想要退出while循環的位置,所以我只是改變了「退出」以成爲「退出」的否定。 – umarqattan 2013-04-20 06:30:01

+0

使用'int'作爲布爾函數,並且很常見,但我絕對更喜歡stdbool風格。 「while」,「if」等等都採用布爾表達式,並且在邏輯上給它們一個數字並不合適。 '退出'不是一個數字,這是一個條件。 – Gauthier 2013-05-29 12:03:29

0

你永遠不會退出循環。休息會打破你的開關。此時應更換

while(1) 

與別的東西,意味着while循環應該退出

0

你休息只剩switch語句,然後在

while(1) 

永遠循環下去,繼續上。

1

您也可以在C中擁有布爾表達式。從1999年開始的C標準具有stdbool.h標題和數據類型bool。 (!)在舊Ç方言,比如一個在Visual Studio 2012,也沒有布爾數據類型,所以你需要使用純整數代替:

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

C99中沒有'stdbool.h'?我覺得很難相信... – Sebivor 2013-04-20 06:23:40

+0

@modifiable lvalue:標準中肯定有。而Visual Studio 2012 _still_沒有它。但你是對的,我不應該說沒有布爾類型。爲了他的緣故,希望他不會陷入微軟。 – 2013-04-20 06:57:52

+0

Visual Studio 2012沒有C編譯器。爲了抵制任何「但是有'編譯爲C代碼'選項」的參數:在過去的十年中編寫的完美有效的C代碼無法使用VS編譯並不罕見。如果它不能編譯C代碼,那麼它不是C編譯器。 – Sebivor 2013-04-20 09:25:20

1

C++可以創建布爾表達式,這是我'm知道,但不在C.

哦?那麼什麼是0 == 0,如果不是布爾表達式呢?如果您指的是bool類型的變量,請確保您的數值爲#include <stdbool.h>

然而,當我寫我的交換機中的break語句,它可以追溯到 到循環的開始,讓我的程序運行下去。忽略 我使用的功能,因爲它們確實有效。我只需要對我的嵌套處理進行一些解釋。謝謝!

不是,它不會回到循環的開始。執行從switch語句的結尾處繼續(緊接在switch的大括號}之後)。在你的情況下,這在功能上與相同,回到循環的開始。

有幾個選項可供您使用。其他人則建議使用唯一的變量來控制你的循環。這是一個好主意,但他們建議使用新的變量,儘管該變量已經存在於您的邏輯中。如果你想解決您的問題這種方式,可以考慮:

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

另外,從return主,當你想退出,或從其他函數中調用exit(0);。如果你想運行額外的清理/輸出代碼,這並不是那麼有用。

在這種情況下,switch控制結構實際上並不比分支的一個鏈條if/else if/else分支更好。如果您要使用if/else if/else分支,則可以更輕鬆地將break;移出循環。當我想要執行流入其他情況時,我會使用一個switch控制結構。

作爲另一種選擇,你可以使用一個goto表達跳出循環到標籤的主要之外。如果循環中有多個可能的退出點,比如分配錯誤之後的處理和清理,這將是最好的。

0

use exit(0);
無論你想要退出。

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

其他方式從while循環出來的可能是使用: return聲明。但是這也將退出當前的功能。

適當的解決方案可能是在交換機內部使用goto label;,然後在while循環外使用label: statement;

如:

while(1){ 
    switch(x){ 

    case 0:goto label; 

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

應該在評論中。這是IMO的非常小的答案。 – 2014-06-15 16:46:23

+0

如果他想完全退出整個程序,這不僅僅是有效嗎?不會'返回0'更合適,但很可能仍然不正確? – 2014-12-15 04:33:49

+0

'退出'從函數退出,'退出'退出整個程序。 – abe312 2015-06-15 18:59:23