显示菜单的奇怪方法

时间:2013-10-31 13:36:22

标签: c

我正在编写一些有SDK的设备。

说我要显示一些菜单。你通常这样做:

void showSomeMenu()
{


...
drawItem(0, "menu option1");
drawItem(1, "menu option2");

while(1)
{
   key = getKey();
   if(key == KEY_ENTER)
   {
   showSomeOtherMenu();
   return; // or break
   }
}
...

}

您可以看到,如果用户点击上面的输入,则可以打开someOtherMenu。现在说someOtherMenu用户希望回去。然后你实现它:

void showSomeOtherMenu()
{


...
// add menu items

while(1)
{
   key = getKey();
   if(key == KEY_ENTER)
   {
   showSomeMenu(); // Will open previous menu (implemented in the first snippet)
   return;
   }
}
...

}

我觉得这种方法很奇怪:有人叫showSomeMenu。 然后按Enter键从showSomeOtherMenu调用。现在从showSomeOtherMenu他点击了 输入,再次拨打showSomeMenu - 但通知,第一次拨打showSomeMenu从未有机会返回。

即使这种方法有效并且菜单会正确显示,但我想知道这是否会以无限循环的函数相互呼叫结束。也许我会遇到堆栈溢出问题或类似的问题。

我有权担心吗?他们的样本中显示了这样做的方法。所以我认为它应该是正确的方法。

2 个答案:

答案 0 :(得分:1)

是的,你是对的,这似乎是非常糟糕的设计。

一般来说,以数据驱动的方式设计这样的事情要好得多,即使用描述所需层次结构的被动数据结构,然后只需一个函数({{1}解释数据并跟踪当前菜单以及允许“移动”的内容。

答案 1 :(得分:0)

每次按下ENTER键,你都会深入到堆栈中一步,没有办法返回。这是recursion,没有基本情况。不要这样做!

一个简单的解决方法是将showSomeOtherMenu()中的代码修改为“返回”而不是递归。

while(1) {
    key = getKey();
    if(key == KEY_ENTER) {
        return;
    }
    // handle other options here
}

更好的方法是保留已访问过的stack个菜单。当你进入一个菜单时,你将它推到堆栈上,当你想要返回时,你弹出堆栈并转到当时位于堆栈顶部的菜单。

e.g:

> Enter menu1      // stack is now [ menu1 ]<- head
> Enter menu2      // stack is now [ menu1, menu2 ]<- head
> Enter menu5      // stack is now [ menu1, menu2, menu5 ]<- head
> Back -> menu2    // stack is now [ menu1, menu2 ]<- head
> Enter menu4      // stack is now [ menu1, menu2, menu4 ]<- head
// etc.

更好的选择是使用某种tree,这样您只需要一个功能来管理菜单。这有点复杂,但实际上每个菜单都有一个节点,每个菜单项都有一个节点的子节点。节点必须有指向其父节点的指针。