0

SDK を持つデバイスをプログラミングしています。

ディスプレイにいくつかのメニューを表示したいとします。通常、次のように進めます。

void showSomeMenu()
{


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

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

}

ユーザーが上記の [Enter] をクリックすると、開くことができることがわかります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です。次に、showSomeOtherMenuEnter キーを押して呼び出されたものから。ここで、showSomeOtherMenuEnter をクリックすると、再び呼び出しが行われますshowSomeMenu、への最初の呼び出しには戻る機会がありませんでした。showSomeMenu

このアプローチは機能し、メニューは正しく表示されますが、相互に関数を呼び出す無限ループで終わるのではないかと思っています。そして、スタックオーバーフローの問題やそのような問題が発生する可能性があります。

私が心配するのは正しいですか?このようにするためのこのアプローチは、サンプルに示されていました。だから私はそれが正しい方法であるべきだと思っていました。

4

2 に答える 2

1

はい、心配するのは当然です。これはひどく悪い設計のようです。

一般に、このようなものはデータ駆動型の方法で設計する方がはるかに優れています。つまり、必要な階層を記述する受動的なデータ構造を使用しrunMenu()てから、データを解釈して現在のメニューを追跡する単一の関数 (または何か) だけを使用します。どの「移動」が許可されているか。

于 2013-10-31T13:43:55.043 に答える
0

ENTER を押すたびに、スタックを 1 ステップ深く掘り下げることになり、戻る方法はありません。これは基本ケースのない再帰です。それをしません!

簡単な修正はshowSomeOtherMenu()、再帰ではなく「戻る」ようにコードを変更することです。

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

より良いアプローチは、アクセスされたメニューのスタックを保持することです。メニューに入ると、それをスタックにプッシュします。戻りたいときは、スタックをポップして、スタックの一番上にあるメニューに移動します。

例えば:

> 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.

さらに良いオプションは、メニューを管理するために必要な機能が 1 つだけになるように、ある種のツリーを使用することです。これはやや複雑ですが、基本的には、各メニューにノードがあり、各メニュー項目にそのノードの子があります。ノードには、親ノードへのポインターが必要です。

于 2013-10-31T13:46:50.360 に答える