我正在編寫一個基於控制檯的應用程序,提示用戶提出一系列問題。 E.g:如何避免使用goto進行一系列提示?
「輸入記錄打開:」
「你想要做X?」
「你想做Y嗎?」
「您確定要繼續嗎?」
如果用戶在任何提示下什麼也不輸入,我想上一層。使用goto這很容易。我能想到的唯一的另一種方式是嵌套循環,看起來遠遠醜陋的,並且對於多個提示非常不方便。儘管如此,必須有一個簡單的方法來做到這一點,我只是想不起來。
我正在編寫一個基於控制檯的應用程序,提示用戶提出一系列問題。 E.g:如何避免使用goto進行一系列提示?
「輸入記錄打開:」
「你想要做X?」
「你想做Y嗎?」
「您確定要繼續嗎?」
如果用戶在任何提示下什麼也不輸入,我想上一層。使用goto這很容易。我能想到的唯一的另一種方式是嵌套循環,看起來遠遠醜陋的,並且對於多個提示非常不方便。儘管如此,必須有一個簡單的方法來做到這一點,我只是想不起來。
你基本上寫一個非常簡單的狀態機 - 使用功能來代表每一個國家:(我將使用隨機僞,因爲你沒有指定語言)
get_information():
return get_record()
ask_record():
record = read_line()
return() if !record
return ask_y(record)
ask_x(record):
x = read_line()
return ask_record() if !x
return ask_y(record, x)
ask_y(record, x):
y = read_line()
return ask_x(record) if !y
return ask_continue(record, x, y)
ask_continue(record, x, y)
continue = read_line()
return ask_y(record, x) if !continue
return (record, x, y)
這是一個很小做法。在某些語言中,調用堆棧會增長,而在其他語言中則不會。如果你有這將導致堆棧成長的語言,你可以用蹦牀,以防止它,通過重寫get_information
做:
x = get_information
while x is function:
x=x()
return x
ask_x(record):
x = read_line()
return (lambda: ask_record()) if !x
return (lambda: ask_y(record, x))
甚至在一些question
結構抽象結果的問題和內存地址:
struct question {
question *next, *prev;
char prompt[];
char **result;
}
然後運行在一個循環中,調用question* run_question(question*)
,轉到 - >下一個或 - > prev,具體取決於答案,直到結果爲NULL(作爲停止條件,結果填入並且沒有問題時剩下)。
如果您使用直接指針訪問的命令式語言,最後的解決方案可能是最「正常」的解決方案。
遞歸地寫而不是迭代地寫。
把它寫成一個簡單的狀態機。
while(running)
{
if (state == INIT)
{
out("enter record");
state = DO_X;
}
else if (state == DO_X)
{
do whatever for x.
state = WHATEVER_NEXT_STATE_IS;
}
}
Upvoted,雖然我恨代碼*這種方式*。當它增長時,你不能輕易分割它。您無法將其設計爲模塊化,並且只需更改一行和新庫,即可插入新路徑。在達到> 10個州後,您無法輕鬆找到哪些鏈接。一般的想法是好的,但。 – viraptor 2010-08-24 02:43:02
這不是for循環所做的(即需要多層嵌套)嗎? – Jason 2010-08-24 01:57:51