看板 C_and_CPP 關於我們 聯絡資訊
基本上 goto 的合理使用方法應該是向下跳躍而不是向上跳躍。 典型的合理應用案例是從巢狀迴圈中跳離, 或是從迴圈內的 switch 敘述內跳離。 這兩種典型用法都是向下跳, 就算是不盲目反對 goto 的也絕對不會打算讓它往上跳。 另一個狀況則是給「程式產生器」方便用, 這類程式產生器產生出來的 C 程式檔通常也不期望 programmer 去閱讀; 但是這類程式產生器通常也會因為 debugging 困難被一些社群批評。 這個萬年作業心得文其實很早就有了定論。 那就是把程式結構化就行了, 跟前篇推文提到的包進函式是一樣的意思。 如果連 while(1) 或 while(true) 這種為迴圈而迴圈的 code 都不願看到, 也不是沒有辦法, 下面直接拿原 po 的 code 來修改。 #include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #define BUFFER_SIZE 256 static bool inputTime(int *x); static bool inputValue(float *m); static void printCost(int x, float m); int main() { int x; float m; while(!inputTime(&x)) { printf("error!\nplease enter right time.\n"); } while(!inputValue(&m)) { printf("error!\n"); } printCost(x, m); return 0; } static bool inputTime(int *x) { char buf[BUFFER_SIZE]; printf("what's time? (1)day , (2)night: "); fgets(buf, BUFFER_SIZE, stdin); if(sscanf(buf, "%d", x) != 1) return false; if(*x != 1 && *x != 2) return false; return true; } static bool inputValue(float *m) { char buf[BUFFER_SIZE]; printf("how long (m)?: "); fgets(buf, BUFFER_SIZE, stdin); if(sscanf(buf, "%f", m) != 1) return false; return true; } static void printCost(int x, float m) { if(x == 1) { printf("$%f.\n", 70 + (m - 1.5) / 0.3 * 5); } else if(x == 2) { printf("$%f.\n", 70 + (m - 1.25) / 0.25 * 5); } } 如果硬要再增加程式可讀性, bool 也能代換成 enum, 強化 while 條件式的自我描述能力。 如果真的是那種把程式當文章寫的神經病, 還會加個 inline function 叫 isValidInput, 寫成 while(!isValidInput(inputTime(&x)))。 反正用 goto 以外的方法增加程式可讀性的方法要多少有多少。 這個就算在戰 goto 好壞的年代裡也沒人想戰, 就算是挺 goto 的陣線看到這種例子也會開砲。 因為不破壞程式結構的向上 goto, 先天上要不就是 C 的迴圈語法可以完全取代的, 要不就是可以改成更易讀的向下 goto。 -- Ling-hua Tseng (uranus@tinlans.org) Department of Computer Science, National Tsing-Hua University Interesting: C++, Compiler, PL/PD, OS, VM, Large-scale software design Researching: Software pipelining for VLIW architectures Homepage: http://www.tinlans.org -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 118.160.108.5 ※ 編輯: tinlans 來自: 118.160.108.5 (04/23 06:11)
ledia:同意, 很多時候初學者用 goto 都只是還無法掌握程式結構 04/23 09:38
VictorTom:推t大:) 04/23 10:18
spider391:推!! 04/23 10:52