而且如果仅仅是常数型的,编译出来的代码执行效率更高,这点在单片机上尤为明显[实际上就是查表的效率高些]。
最近测试了下,使用表驱动方式调用函数,
但是发现参数的个数如果不定就是个麻烦了
但是gcc似乎在某些时候的检测并不那么严格,所以下面的代码还是可以无错运行的
[但是g++是会报错的,不过c++已经有很好的物件导向了,一般也不用函数指针了]
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);
}
#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
那么如果函数需要有些有返回值呢?
将上面的程序修改如下
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);
}
#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