51系列单片机支持函数指针,其写法如下:
typedef void (* FuncPtr)();
int a;
void func1(){
a = 10;
}
void func2(){
a = 20;
}
void func3(){
a = 30;
}
int main(){
FuncPtr ptr;
if (a == 10){
ptr = func1;
}
else if (a == 20){
ptr = func2;
}
else {
ptr = func3;
}
ptr();
}
东软载波的8位单片机不支持函数指针,需要改写成switch…case…的形式,例程如下。
1.1 FuncHelper.h
例程说明:
移植的核心文件是FuncHelper.h,其内容如下:
C例程:
op(func1)
op(func2)
op(func3)
#undef op
用户可以在这个文件中添加所有原来使用函数指针调用的函数。
1.2 Demo2.h
例程说明:
该文件用宏定义的形式实现原来函数指针的赋值和调用。
C例程:
#ifndef DEMO2_H
#define DEMO2_H
#define FuncPtr unsigned int
#define _get(a) CNT_##a
#define op(a) CNT_##a,
enum
{
CNT_NONE = 0,
#include "FuncHelper.h"
};
#define op(a) extern void a();
#include "FuncHelper.h"
static void _call(unsigned int id)
{
#define op(a) case CNT_##a: a(); break;
switch(id)
{
#include "FuncHelper.h"
}
}
#endif
1.3 Demo2.c
例程说明:
该文件替换了原来51单片机的函数指针调用方式。
C例程:
#include "Demo2.h"
int a;
void func1(){
a = 10;
}
void func2(){
a = 20;
}
void func3(){
a = 30;
}
int main(){
FuncPtr ptr;
if (a == 10) {
ptr = _get(func1); //ptr = func1;
}
else if (a == 20) {
ptr = _get(func2); //ptr = func2;
}
else {
ptr = _get(func3); //ptr = func3;
}
_call(ptr); //ptr();
}
上面的程序展开后变成:
enum {
CNT_NONE = 0,
CNT_func1 = 1,
CNT_func2 = 2,
CNT_func3 = 3,
};
extern void func1();
extern void func2();
extern void func3();
static void _call(unsigned int id){
switch(id) {
case CNT_ func1: func1(); break;
case CNT_ func2: func2(); break;
case CNT_ func3: func3(); break;
}
}
int a;
void func1(){
a = 10;
}
void func2(){
a = 20;
}
void func3(){
a = 30;
}
int main(){
unsigned int ptr;
if (a == 10) {
ptr = CNT_func1;
}
else if (a == 20) {
ptr = CNT_func2;
}
else {
ptr = CNT_func3;
}
_call(ptr);
}