我正在编写一个基于控制台的应用程序,提示用户提出一系列问题。 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