搜索
bottom↓
回复: 8

请教函数指针的用法

[复制链接]

出0入55汤圆

发表于 2017-10-14 19:43:47 | 显示全部楼层 |阅读模式
本帖最后由 jssd 于 2017-10-14 20:33 编辑

  1. void Fun1(void)
  2. {
  3.         LCD_DrawBox(0,0,127,63,BoxModel_Draw,FillType_NoFill);
  4.         LCD_DisplayStr("test",0,0,FN_ASC8x16,FN_ST12,ALPHA_YES,LCD_Graphic_Draw);
  5. }

  6. struct _Page      
  7. {
  8.         void (*pFun)(void);
  9. };

  10. struct _Page menuPage[MAX_PAGE_NUM];

  11. void Init(void)
  12. {
  13.         menuPage[0].pFun = Fun1;
  14. }

  15. void Show(void)
  16. {
  17.         (menuPage[0].pFun)();        //乱码
  18. //        Fun1();                                //正常
  19. }
复制代码


如上代码中,直接用Fun1();则显示正常,使用(menuPage[0].pFun)();则显示乱码
因道行浅,看不出问题出在哪,故求助,非常感谢!

补充:
还有一点就是
void Fun1(void)
{
        LCD_DrawBox(0,0,127,63,BoxModel_Draw,FillType_NoFill);
        LCD_DisplayStr("test",0,0,FN_ASC8x16,FN_ST12,ALPHA_YES,LCD_Graphic_Draw);
}
这个函数去掉 LCD_DrawBox(0,0,127,63,BoxModel_Draw,FillType_NoFill);后显示是正常的,加上就不正常,但如果不是这样使用,单独使用又是正常的。证明函数本身没问题

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

发表于 2017-10-14 20:01:02 | 显示全部楼层
可能跟编译器有关了吧 这个初步判断是没问题的

出0入55汤圆

 楼主| 发表于 2017-10-14 20:27:43 | 显示全部楼层
ywlzh 发表于 2017-10-14 20:01
可能跟编译器有关了吧 这个初步判断是没问题的


感谢回复,下面是完整的程序,上面的是示意,用的是STC单片机,MDK5
  1. #include "menu.h"
  2. #include "lcd12864.h"
  3. #include "icon.h"

  4. //图标
  5. struct _Icon   
  6. {
  7.     unsigned char *pPic;
  8.         unsigned char x;
  9.         unsigned char y;
  10.         unsigned char w;
  11.         unsigned char h;
  12.         unsigned char alpha;
  13.         unsigned char type;
  14. };

  15. //字符串
  16. struct _String   
  17. {
  18.         unsigned char *pStr;
  19.         unsigned char x;
  20.         unsigned char y;
  21.         unsigned char fontASC;
  22.         unsigned char fontHZ;
  23.         unsigned char alpha;
  24.         unsigned char type;
  25. };

  26. //菜单项目
  27. struct _Item        
  28. {
  29.         unsigned char id;//项目id,在一个页面内独一无二,值从1开始
  30.     struct _Icon icon;//项目图标
  31.         struct _String str;//项目字符串
  32.         struct _Icon focus;//项目焦点图片,获得焦点才显示
  33. //        void (*Subs)();//项目响应函数,当确认或取消时执行
  34. };

  35. //页面
  36. struct _Page      
  37. {
  38.         unsigned char itemNum;//一个页面包涵的项目总数
  39.     struct _Item *pItem;//一个页面包涵的项目指针
  40.         void (*pFun)(void);//显示页面之前调用的函数
  41. };


  42. //菜单定义区
  43. #define MAX_PAGE_NUM        1
  44. xdata struct _Page menuPage[MAX_PAGE_NUM];

  45. #define MENU_MAIN                0 //主菜单
  46. #define MENU_MAIN_ITEM        4 //主菜单项目数量
  47. xdata struct _Item menuMain[MENU_MAIN_ITEM];

  48. //菜单全局变量
  49. unsigned char pageID = 0;//要显示的页面id号
  50. unsigned char focusID = 0;//获得焦点的id号,0表示没有项目获得焦点


  51. void MainMenuDisplayInit(void)
  52. {
  53.         LCD_DrawBox(0,0,127,63,BoxModel_Draw,FillType_NoFill);
  54.         LCD_DisplayStr("test",0,0,FN_ASC8x16,FN_ST12,ALPHA_YES,LCD_Graphic_Draw);
  55. }

  56. //函数说明:根目录初始化
  57. void MainMenuInit(void)
  58. {
  59.         //初始化页面
  60.         menuPage[MENU_MAIN].itemNum = MENU_MAIN_ITEM;
  61.         menuPage[MENU_MAIN].pItem = menuMain;
  62.         menuPage[MENU_MAIN].pFun = MainMenuDisplayInit;
  63.        
  64.         //初始化项目
  65.         menuMain[0].id = 1;//

  66.         menuMain[0].icon.pPic = 0;
  67.         menuMain[0].icon.x = 0;
  68.         menuMain[0].icon.y = 0;
  69.         menuMain[0].icon.w = 0;
  70.         menuMain[0].icon.h = 0;
  71.         menuMain[0].icon.alpha = 0;
  72.         menuMain[0].icon.type = 0;
  73.        
  74.         menuMain[0].str.pStr = "0";
  75.         menuMain[0].str.x = 20;
  76.         menuMain[0].str.y = 20;
  77.         menuMain[0].str.fontASC = FN_ASC8x16;
  78.         menuMain[0].str.fontHZ = FN_ST12;
  79.         menuMain[0].str.alpha = ALPHA_YES;
  80.         menuMain[0].str.type = LCD_Graphic_Draw;
  81.        
  82.         menuMain[0].focus.pPic = 0;
  83.         menuMain[0].focus.x = 0;
  84.         menuMain[0].focus.y = 0;
  85.         menuMain[0].focus.w = 0;
  86.         menuMain[0].focus.h = 0;
  87.         menuMain[0].focus.alpha = 0;
  88.         menuMain[0].focus.type = 0;
  89.        
  90.         menuMain[1].id = 2;//

  91.         menuMain[1].icon.pPic = 0;
  92.         menuMain[1].icon.x = 0;
  93.         menuMain[1].icon.y = 0;
  94.         menuMain[1].icon.w = 0;
  95.         menuMain[1].icon.h = 0;
  96.         menuMain[1].icon.alpha = 0;
  97.         menuMain[1].icon.type = 0;
  98.        
  99.         menuMain[1].str.pStr = "60";
  100.         menuMain[1].str.x = 90;
  101.         menuMain[1].str.y = 20;
  102.         menuMain[1].str.fontASC = FN_ASC8x16;
  103.         menuMain[1].str.fontHZ = FN_ST12;
  104.         menuMain[1].str.alpha = ALPHA_YES;
  105.         menuMain[1].str.type = LCD_Graphic_Draw;
  106.        
  107.         menuMain[1].focus.pPic = 0;
  108.         menuMain[1].focus.x = 0;
  109.         menuMain[1].focus.y = 0;
  110.         menuMain[1].focus.w = 0;
  111.         menuMain[1].focus.h = 0;
  112.         menuMain[1].focus.alpha = 0;
  113.         menuMain[1].focus.type = 0;
  114.        
  115.         menuMain[2].id = 3;//

  116.         menuMain[2].icon.pPic = 0;
  117.         menuMain[2].icon.x = 0;
  118.         menuMain[2].icon.y = 0;
  119.         menuMain[2].icon.w = 0;
  120.         menuMain[2].icon.h = 0;
  121.         menuMain[2].icon.alpha = 0;
  122.         menuMain[2].icon.type = 0;
  123.        
  124.         menuMain[2].str.pStr = "1";
  125.         menuMain[2].str.x = 10;
  126.         menuMain[2].str.y = 50;
  127.         menuMain[2].str.fontASC = FN_ASC8x16;
  128.         menuMain[2].str.fontHZ = FN_ST12;
  129.         menuMain[2].str.alpha = ALPHA_YES;
  130.         menuMain[2].str.type = LCD_Graphic_Draw;
  131.        
  132.         menuMain[2].focus.pPic = 0;
  133.         menuMain[2].focus.x = 0;
  134.         menuMain[2].focus.y = 0;
  135.         menuMain[2].focus.w = 0;
  136.         menuMain[2].focus.h = 0;
  137.         menuMain[2].focus.alpha = 0;
  138.         menuMain[2].focus.type = 0;
  139.        
  140.         menuMain[3].id = 4;//

  141.         menuMain[3].icon.pPic = 0;
  142.         menuMain[3].icon.x = 0;
  143.         menuMain[3].icon.y = 0;
  144.         menuMain[3].icon.w = 0;
  145.         menuMain[3].icon.h = 0;
  146.         menuMain[3].icon.alpha = 0;
  147.         menuMain[3].icon.type = 0;
  148.        
  149.         menuMain[3].str.pStr = "1";
  150.         menuMain[3].str.x = 80;
  151.         menuMain[3].str.y = 50;
  152.         menuMain[3].str.fontASC = FN_ASC8x16;
  153.         menuMain[3].str.fontHZ = FN_ST12;
  154.         menuMain[3].str.alpha = ALPHA_YES;
  155.         menuMain[3].str.type = LCD_Graphic_Draw;
  156.        
  157.         menuMain[3].focus.pPic = 0;
  158.         menuMain[3].focus.x = 0;
  159.         menuMain[3].focus.y = 0;
  160.         menuMain[3].focus.w = 0;
  161.         menuMain[3].focus.h = 0;
  162.         menuMain[3].focus.alpha = 0;
  163.         menuMain[3].focus.type = 0;
  164. }



  165. /**************************************************************

  166. *  函数说明:目录初始化函数                                   *

  167. **************************************************************/
  168. void Menu_Init(void)
  169. {
  170.     MainMenuInit();
  171. }


  172. /**************************************************************

  173. *  函数说明:目录显示函数                                     *

  174. **************************************************************/
  175. void Menu_Show(void)
  176. {
  177.         char i;
  178.         struct _Item *disItem;
  179.         short maxItems;
  180.        
  181.         //不在显示范围
  182.         if(pageID>=MAX_PAGE_NUM) return;
  183.        
  184.         //获取item
  185.         disItem = menuPage[pageID].pItem;
  186.        
  187.         //获取item数目
  188.         maxItems = menuPage[pageID].itemNum;
  189.        
  190.         //界面预处理
  191.         if(menuPage[pageID].pFun!=0)
  192.         {
  193.                 (*menuPage[pageID].pFun)();
  194.         }

  195. //        MainMenuDisplayInit();
  196.        
  197.         for(i=0;i<maxItems;i++)
  198.         {
  199.                 if(disItem[i].icon.pPic!=0)
  200.                 {//显示icon
  201.                         //void LCD_DisplayPic(const uchar *pPic, uint x0 ,uint y0 , uint w ,uint h,uchar alpha,uchar type);
  202.                         LCD_DisplayPic(disItem[i].icon.pPic,disItem[i].icon.x,disItem[i].icon.y,disItem[i].icon.w,disItem[i].icon.h,disItem[i].icon.alpha,disItem[i].icon.type);
  203.                 }
  204.                 if(disItem[i].str.pStr!=0)
  205.                 {//显示字符串
  206.                         //void LCD_DisplayStr(const uchar *pStr, uint x0 ,uint y0 , uchar fontASC, uchar fontHZ,uchar alpha,uchar type);
  207.                         LCD_DisplayStr(disItem[i].str.pStr,disItem[i].str.x,disItem[i].str.y,disItem[i].str.fontASC,disItem[i].str.fontHZ,disItem[i].str.alpha,disItem[i].str.type);
  208.                 }
  209.                 if(focusID==disItem[i].id&&disItem[i].focus.pPic!=0)
  210.                 {//显示Focus
  211.                         //void LCD_DisplayPic(const uchar *pPic, uint x0 ,uint y0 , uint w ,uint h,uchar alpha,uchar type);
  212.                         LCD_DisplayPic(disItem[i].focus.pPic,disItem[i].focus.x,disItem[i].focus.y,disItem[i].focus.w,disItem[i].focus.h,disItem[i].focus.alpha,disItem[i].focus.type);
  213.                 }
  214.         }
  215. }


复制代码

出0入4汤圆

发表于 2017-10-14 20:39:23 | 显示全部楼层

貌似没有问题

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2017-10-15 11:25:11 | 显示全部楼层
楼主是用函数指针做状态机,写的不错。学习了。

出0入55汤圆

 楼主| 发表于 2017-10-16 10:31:56 | 显示全部楼层
su33691 发表于 2017-10-15 11:25
楼主是用函数指针做状态机,写的不错。学习了。

惭愧了~~我都不知道这个函数指针做状态机,这代码是根据傻孩子的菜单代码改的。

出0入0汤圆

发表于 2021-8-10 11:27:24 | 显示全部楼层
我觉得应该是Fun1没有在定义结构体变量的时候,给函数成员

出0入4汤圆

发表于 2021-8-10 12:38:46 | 显示全部楼层
Keil C51编译器不能直接这样用函数指针,需要在“BL51 Misc”-“Overlay”中填入:  ?PR?MAIN?MAIN~(FUN1),SHOW!FUN1,来修改调用树

出0入0汤圆

发表于 2021-8-10 17:33:35 | 显示全部楼层
MARK   函数指针做状态机    学习哈
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-24 12:19

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表