c语言表驱动参数传递[0803]

最近发现使用表驱动确实可以大大美化代码,
而且如果仅仅是常数型的,编译出来的代码执行效率更高,这点在单片机上尤为明显[实际上就是查表的效率高些]。
最近测试了下,使用表驱动方式调用函数,
但是发现参数的个数如果不定就是个麻烦了
但是gcc似乎在某些时候的检测并不那么严格,所以下面的代码还是可以无错运行的
[但是g++是会报错的,不过c++已经有很好的物件导向了,一般也不用函数指针了]

ContractedBlock.gif ExpandedBlockStart.gif Code
#include <stdio.h>


typedef  
void (*Func)();
//这一行如果改为
//typedef void (*Func)(int x);
//那么下面的代码中无论调用的函数是否有形参都要传递至少一个参数


typedef 
struct {
 
int flag;
 Func func;
} Table;



void a()
{
    printf(
"output -> a  \n");
}
void a2()
{
    printf(
"output -> a2  \n");
}
void b(int x)
{
    printf(
"output -> b(%d)  \n",x);
}
void error()
{
    printf(
"error:table:out of range\n");
}
 
static const Table table[] = {
 {
1,a},
 {
2,a2},
 {
3,b},
 {
4,error}
//最后这个仅仅是为了检错
};



Func process(
int flag)
{
    
int i;
 
for(i = 0; i < sizeof(table)/sizeof(Table)-1; i++)
    {
        
if(flag==table[i].flag)
        {
           
return table[i].func;
        }
   }
 
return table[i].func;
}

int main (int argc, char *argv[])
{
    process(
1)();
    process(
2)(30);
    
//从运行的结果来看,忽略了此处参数的传递
    process(1)();
    process(
3)(20);   
    process(
100)();   
    
return(0);
}

 

程序运行结果如下
output -> a  
output -> a2  
output -> a  
output -> b(20)  
error:table:out of range
那么如果函数需要有些有返回值呢?
将上面的程序修改如下
ContractedBlock.gif ExpandedBlockStart.gif Code
#include <stdio.h>


typedef  
int (*Func)();



typedef 
struct {
 
int flag;
 Func func;
} Table;

void a()
{
    printf(
"output -> a  \n");
}
void a2()
{
    printf(
"output -> a2  \n");
}
void b(int x)
{
    printf(
"output -> b(%d)  \n",x);
}
int b2(int x)
{
    printf(
"output -> b(%d)  \n",x);
    
return x+100;
}
void error()
{
    printf(
"error:table:out of range\n");
}
 
static const Table table[] = {
 {
1,a},
 {
2,a2},
 {
3,b},
 {
4,b2},
 {
5,error}
//最后这个仅仅是为了检错
};



Func process(
int flag)
{
    
int i;
 
for(i = 0; i < sizeof(table)/sizeof(Table)-1; i++)
    {
        
if(flag==table[i].flag)
        {
           
return table[i].func;
        }
   }
 
return table[i].func;
}

int main (int argc, char *argv[])
{
    
int a=0;
    a
=process(1)();
    printf(
"now a is %d\n",a);
    a
=process(2)(30);
    printf(
"now a is %d\n",a);
    a
=process(1)();
    printf(
"now a is %d\n",a);
    a
=process(3)(20);   
    printf(
"now a is %d\n",a);
    a
=process(4)(100);
    printf(
"now a is %d\n",a);
    a
=process(100)();   
    printf(
"now a is %d\n",a);
    
return(0);
}

从编译的结果,可以看到gcc已经能够正确的报出警告
但程序还是能够运行的,比较有意思的是对于实际上不应返回的函数此时会使a改变
其输出结果如下
output -> a  
now a is 14
output -> a2  
now a is 15
output -> a  
now a is 14
output -> b(20)  
now a is 18
output -> b(100)  
now a is 200
error:table:out of range

转载于:https://www.cnblogs.com/pingf/archive/2009/08/03/1537730.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值