liuxiaohui17 发表于 2015-1-21 15:02:53

请教“傻孩子”大师两种菜单的优缺点

最近看论坛里的菜单实现方法,发现有两种讨论的比较多,如下(1方法我不清楚出处,在此注明;2方法就是你写的菜单那种)
1方法(有不少文章提到此种方式)此处截取部分
typedef struct
   {
      uchar current;
      uchar up;//暂定键值6为up
      uchar down;//暂定键值15为down
      //uchar enter;
      void (*current_operation)();
      } key_table;
      
key_tabletable=
{
      {0,11,1,(*fun0)},      // 显示“菜单”
      {1,0,2,(*fun1)},      // 显示“1系统设置”
      {2,1,3,(*fun2)},      // 显示“2控制时间”
    {3,2,4,(*fun3)},      // 显示“3查询温度”
    {4,3,5,(*fun4)},   // 显示“温度×××C”
      {5,4,6,(*fun5)},   // 显示“(时钟)”
      {6,5,7,(*fun6)},   // 显示“设置时钟年”
      {7,6,8,(*fun7)},   // 显示“设置时钟月”
      {8,7,9,(*fun8)},   // 显示“设置时钟日”
      {9,8,10,(*fun9)},    // 显示“设置时钟时”
      {10,9,11,(*fun10)},// 显示“设置时钟分”
      {11,10,0,(*fun11)},// 显示“设置时钟秒”
};

2方法(详见http://www.amobbs.com/thread-591361-1-1.html)此处截取部分

/***********************

*   结构体宏定义   *

***********************/

struct MenuItem      

{

    char MenuCount;

    char *DisplayString;

    void (*Subs)();

    struct MenuItem *ChildrenMenus;

    struct MenuItem *ParentMenus;

}NULL_MENU;



void NULL_FUNCTION(void){}



我们看到,菜单的最小单元MenuItem的组成其实非常简单:

菜单项所在层的菜单项数目(度);

菜单项显示出来的字符串;

菜单需要执行的功能的函数指针(可以为空);

孩子指针(表明选择该菜单项后,跳转到哪个子菜单去);

父指针(表明选择ESC后,跳转到哪个菜单去);



看一个菜单实例:

(源代码)



struct MenuItem MainMenu;

struct MenuItem TimeMenu;

struct MenuItem VoiceMenu;

struct MenuItem RobotMenu;

struct MenuItem FlashMenu;


想请教一下两种方式的优缺点,谢谢

262619890 发表于 2015-1-21 15:51:34

楼主,这个内容的帖子你发了不少了

xjmlfm1 发表于 2015-1-21 15:53:11

如果团队都是高手,可以用这种方法。
否则,还是老老实实的用switch结构吧,新来的人也能轻松上手。
傻孩子那种方法,碰到新人,会改得惨不忍睹,漏洞百出。

liuxiaohui17 发表于 2015-1-21 20:56:20

傻孩子的方法正在测试中,都试试才有感觉

bad_fpga 发表于 2015-1-21 21:37:39

第一种菜单的出处在这里
http://www.amobbs.com/thread-798580-1-1.html

bitter 发表于 2015-1-21 22:32:13

不知道优缺点,就自己测试一下吗?
不同的人,同一件事的不同阶段的看法都不同。
优缺点还是自己测评一下,比如三层菜单,每层10个子菜单的资源占用。(我很期待结果啊)
就好像 状态机好 还是 回调函数好,楼主以为呢?

end2000 发表于 2015-1-22 00:20:48

试着分析你列出的2个数据结构:

方法1的:


蓝色框的是每个菜单项,蓝色箭头是接收事件up, 红色箭头是接收事件down,事件enter没画出来。
要迁移到下一个菜单项时,FSM需要查找table[]数组得到新菜单项。

方法2的:

和方法1类似,但它直接存储了指向下一个菜单项的指针,FSM不需要查找新菜单项。
你的例子里有   MainMenu;TimeMenu;VoiceMenu;RobotMenu;FlashMenu;
5个类似的菜单项,我只画了其中一个。你自己看代码可以补齐。

要比较优缺点,你先要给出你的评判标准才行。

从2张图可以看出本质上这2种方法是一致的,都是一个简单的有限状态机在迁移。
方法1需要手工调整菜单之间的转移关系,也就是那个table[]数组。
方法2代码写的比较规范,但它没有把菜单const,加上了几个Init函数,算是一个小小的不足吧。



机器人天空 发表于 2015-1-22 08:38:01

已经习惯用第一种,结构很清晰

与狼共舞 发表于 2015-1-22 09:31:45

我也觉得第一种比较好理解,循环选择跟SWITCH语句相似

Excellence 发表于 2015-1-22 09:35:50

第一种用了8,9年。。

liuxiaohui17 发表于 2015-1-23 16:08:46

8楼说的对,优缺点在于评判的标准,我想知道优缺点是想知道哪一种更有利于运行,维护,以及更好的应用性能。两种方法其实来看实质还是一样的,都是指针形式的状态机,只不过第二种方法将父子之间的关系分开不像第一种并行。两种我都测试过(第二种测试时发现一个菜单的子菜单多余页面显示时多出的部分显示还不够清晰明确,也才测试修改)。第二种我还在琢磨。谢谢大家的分享

mcu_lover 发表于 2015-1-23 18:46:50

http://www.amobbs.com/thread-5582451-1-1.html

zhoulei123 发表于 2015-2-7 10:30:15

{:smile:}{:smile:}{:smile:}{:smile:}{:smile:}{:smile:}

GZZXB 发表于 2015-2-10 09:17:36

从理解和移植来说.傻孩子的结构我比较喜欢,可是用不上,没那么多ram来折腾{:lol:}

Gorgon_Meducer 发表于 2015-2-10 10:13:40

GZZXB 发表于 2015-2-10 09:17
从理解和移植来说.傻孩子的结构我比较喜欢,可是用不上,没那么多ram来折腾 ...

我一直搞不懂,为啥说我的方法RAM占用大,明明菜单内容都是常量,加个const更改下初始化方式就可以了,一点都不懂得变通?你们真的理解这个菜单么?

Me、小丁丁 发表于 2015-3-17 11:30:20

能不能给个傻孩子原版的链接,找半天都找不到,难道是打开方式不对?谢谢

add00 发表于 2015-3-21 23:59:32

用的第一种菜单实现,在理解第二种ing。。。

dxz0804 发表于 2015-3-22 20:21:55

一直用第一种方式,挺好

ponder2077 发表于 2015-3-23 06:49:41

备注一下,

1125526801 发表于 2015-4-16 09:39:04

手机看不方便,转电脑上学习去

MCUStudent 发表于 2015-12-22 22:05:54

以前一直看不懂这两种菜单,经过很长时间的学习,终于能看懂了。这些天正在写LCD的多级菜单(还没写完),还是有一定的困难,不过在本人的“不懈努力下”都克服掉了。通过学习,感觉第一种形式的菜单相对比傻孩子的要容易学一些,我是通过第一种才看懂了第二种,一开始就是用第一种写的多级菜单,感觉有些零散(应该是学习的不深入),于是一直用第二种写,确实如三楼所说“傻孩子那种方法,碰到新人,会改得惨不忍睹,漏洞百出”。我就是一边写一边改终于达到了“惨不忍睹,漏洞百出”的境界。头确实很大。再后来一遍一遍不断重复,思考,终于走过来了。还会继续写下去直到完成。
另外我也不知道“为啥说傻孩子的方法RAM占用大,明明菜单内容都是常量”,都是用code定义的数组,我的程序“Program Size: data=68.6 xdata=0 code=21537”应该不算多吧。

在这里要谢谢傻孩子,通过LCD的多级菜单,加强了对结构体的学习,加深了对结构体的理解。本人菜鸟一枚,以上仅凭个人感觉。

bigwei 发表于 2015-12-23 21:06:38

学习中,多谢分享。

xinyuan123 发表于 2018-1-11 00:51:00

感谢分享,初次接触需要仔细琢磨
页: [1]
查看完整版本: 请教“傻孩子”大师两种菜单的优缺点