免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12
最近访问板块 发新帖
楼主: chinaren_fy
打印 上一主题 下一主题

[C] 一个实际中遇到的想急切解决的问题 [复制链接]

论坛徽章:
0
11 [报告]
发表于 2008-07-22 23:14 |只看该作者
.... 这个东西 我一般是这么做的。

以nStatus的大小
建立一个全局的数组
typedef struct function
{
       void (*a_proc)(void);
      void (*b_proc)(void);
};

static function function[maxsize] ;

然后 将预先将所有函数指针放在这个function里面

以后利用 nStatus 的值直接 获取到function[nStatus ];
就能拿到2个函数指针,直接操作了。

而数据那里记录就不需要存函数指针了。

论坛徽章:
0
12 [报告]
发表于 2008-07-22 23:21 |只看该作者
C还是C++啊?C++可以用继承/包含,C的话只能也能这么干,不过需要做不太安全的强造型处理。

论坛徽章:
0
13 [报告]
发表于 2008-07-23 10:10 |只看该作者
struct data_ops{
      void (*a_proc)(struct option*);
      void (*b_proc)(struct option*);
      .................................
}

struct option{
      struct data_ops* ops;
      void* data;  //数据链头指针
}

#define  A_PROC(OPTION) (*(OPTION)->ops->a_proc)(OPTION)
#define  B_PROC(OPTION) (*(OPTION)->ops->a_proc)(OPTION)
...................................................................

论坛徽章:
8
CU大牛徽章
日期:2013-04-17 10:59:39CU大牛徽章
日期:2013-04-17 11:01:45CU大牛徽章
日期:2013-04-17 11:02:15CU大牛徽章
日期:2013-04-17 11:02:36CU大牛徽章
日期:2013-04-17 11:02:58技术图书徽章
日期:2013-12-04 10:48:50酉鸡
日期:2014-01-03 10:32:30辰龙
日期:2014-03-06 15:04:07
14 [报告]
发表于 2008-07-23 12:27 |只看该作者
原帖由 chinaren_fy 于 2008-7-22 19:21 发表
有一个结构体,定义如下:
typedef struct tagStatus
{
      int  nStatus;
      void (*a_proc)(void);
      void (*b_proc)(void);
} STATUS;
根据nStatus的不同,有不同的a_proc和b_proc处理,目 ...


C语言场合,可以:


  1. enum status_handle { status1 = 0, status2, ...};

  2. //不好意思,typedef语法忘了,这里不一定对,明白意思就是
  3. typedef Proc_a_type void p(void);

  4. //假设有500个状态
  5. #define Max_Status_Num 500

  6. //声明一个proc_a的数组
  7. #define Declare_Proc_a_Entries Proc_a_Type Proc_a_Entry[Max_Status_Num]={0}

  8. //设置特定的status_handle对应哪个proc_a
  9. #define Reg_Proc_a_For_Handle(status_handle1, Proc_a) Proc_a_Entry[status_handle1]=Proc_a

  10. //这个函数也可以定义成宏
  11. //这样在编译期即可确定status的场合,可以得到编译器的优化支持,获得更佳性能
  12. void Call_Proc_a_For_Handle(status_handle handle)
  13. {
  14.    //检查参数合法性
  15.    assert(handle < Max_Status_Num && handle >= 0);

  16.    //检查对应proc_a是否存在
  17.    if (Proc_a_Entry[handle]==NULL)
  18.    {
  19.      //to do: print error msg or throw
  20.      return;
  21.    }
  22.    Proc_a_Entry[handle]();
  23. }
复制代码




proc_b和proc_c类似处理即可。

在实现文件里可以这样使用:


  1. Declare_Proc_a_Entries;
  2. Declare_Proc_b_Entries;
  3. Declare_Proc_c_Entries;

  4. //声明status1的proc_a处理函数
  5. void proc_a_status1(void)
  6. {
  7.   //do sth
  8. }
  9. //注册之
  10. Regist_Proc_a_For_Handle(status1, proc_a_status1);
  11. //如果status2也可用它处理,可这样注册之
  12. Regist_Proc_a_For_Handle(status2, proc_a_status1);


  13. //已知status,调用对应的proc_a
  14. cur_status_handle = status1;
  15. Call_Proc_a_For_Handle(cur_status_handle);
复制代码




以上仅供参考,不保证能通过编译。


在c++、泛型支持下,应该还有更简洁优雅的解决方案;现在没时间,等以后再写吧。

论坛徽章:
0
15 [报告]
发表于 2008-07-23 15:34 |只看该作者

回复 #14 shan_ghost 的帖子

哥哥,名字都這麽長,眼都看花了...

论坛徽章:
2
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:56:11
16 [报告]
发表于 2008-07-23 15:44 |只看该作者
typedef struct tagStatusEx
{
      void (*c_proc)(void);
} STATUS_EX;

再定义一个扩展类型,并定义对应的数组.


  1. for (i = 0; i < STATUS_LEN; i++) {
  2. switch (nStatus) {
  3. case A_PROC:
  4.    (*Status[i].a_proc)();
  5.     break;  
  6. case B_PROC:
  7.    (*Status[i].b_proc)();
  8.     break;  
  9. case C_PROC:
  10.    (*StatusEx[i].c_proc)();
  11.     break;
  12. default:
  13.     /* error */
  14.     break;
  15. }
  16. }
复制代码

[ 本帖最后由 cobras 于 2008-7-23 15:46 编辑 ]

论坛徽章:
0
17 [报告]
发表于 2008-07-23 22:12 |只看该作者
TO14#:shan_ghost
真是太棒了。
别的不说,代码具有非常好的易读性!

论坛徽章:
0
18 [报告]
发表于 2008-07-23 22:25 |只看该作者
把不同的nStatus弄一个enum传给proc当参数
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP