其实函数指针和普通类型的指针没什么区别,只不过从代码的表现形式上略有差异罢了,回顾一下,下面定义两个在普通不过的”变量“,仔细推敲以下他们的区别。(插几句,现在所做的工作虽谈不上是科研,呵呵,和人家比不了,通俗定义可以叫工科男吧,以前做事貌似从未对做过的学问或者工作仔细推敲,但现在不知道什么时候进化到这个状态)
// 定义1:int型变量
int var1;
// 定义2:int型指针变量
int* var2;
那么注意int型指针变量中的 “指针”一词儿,它应该和”int型“结合在一起理解还是应该和”变量“一词结合在一起来理解“int型指针变量”更好呢?
从定义1和定义2后面的文字来讲,他们的语法有且仅有两个部分组成 数据类型+变量,关键是定义2中的“指针”一词应该归到数据类型里边呢?还是归到变量里边呢?
理解一:指针归到数据类型中,那么就是说int*和int都是数据类型喽!int是数据类型,int*是么?
理解二:指针归到变量中,不应该这么说,从汉语语言语法角度来讲:定义1中int型应该是修饰变量一词的,那么定义2中int型和指针应该都是修饰变量的,定义1中的语义对应到代码上应该是int型--int 变量--var1;那么
// 定义2-1:int型指针 变量
int* var2;
// 定义2-2:int型 指针变量
int *var2;
按定义2-1来讲的话 int*是个数据类型,语法上是这么定义的么?那么在硬件上怎么描述呢?
按定义2-2来讲的话 int 是个数据类型,理解。*var是个指针变量。那么在硬件上怎么描述呢?(如您看到此处请给出您对以上问题的理解)
回过神儿来,再说说怎么定义一个函数指针,其代码的表现形式(用实际代码展示)是什么样的?他又和定于普通类型变量(在代码表现形式上)有什么区别呢?
// 2015-02-08
//
//
//* 1.函数的普通声明
//* 2.函数的普通定义
//* 3.typedef定义函数指针类型 数据类型
//* 4.定义函数指针变量
//* 5.使用函数指针类型定义的变量
//* 6.定义(参数中带有函数指针的)函数以及使用,如下
// 6-1.Func4
// 6-2.Function1
// 6-3.Function2
//* 7. 如何优化函数入参的个数
// 7-1.Function1
// 7-2.Function2
//
#define Length 100
#define NULL ((void*)0)
// 定义(函数指针型)数据类型
typedef int (*pFunc1)();
typedef int (*pFunc2)(int a,int b);
typedef int* (*pFunc3)(int* pa,int b);
typedef int (*pFunc4)(int (*pFunc2_)(int a,int b),int c,int d,int e);
typedef struct tagCombinationStruct
{
void* __f1;// unused;for Func1() function
int _f2a;
int _f2b;
int* _f3a;
int _f3b;
pFunc2 _f4a;
int _f4c;
int _f4d;
int _f4e;
tagCombinationStruct()
{
__f1=NULL;
_f2a=0;
_f2b=0;
_f3a=0;
_f3b=0;
_f4a=(pFunc2)NULL;
_f4c=0;
_f4d=0;
_f4e=0;
}
}CombinationStruct;
// 函数声明
int Func1();
int Func2(int a,int b);
int* Func3(int* pa,int b);
int Func4(int (*pFunc2_)(int a,int b),int c,int d,int e);
void Function1(pFunc1 F1,pFunc2 F2,pFunc3 F3,pFunc4 F4,int f2a,int f2b,int* f3a,int f3b,pFunc2 f4a,int f4c,int f4d,int f4e);
void Function2(pFunc1 F1,pFunc2 F2,pFunc3 F3,pFunc4 F4,CombinationStruct com);
void main()
{
int varF4e=0;
int *pvarF4e=(int*)NULL;
// 基本函数使用
Func1();
Func2(1989,1989);
Func3(0000,1989);
Func4(Func2,1989,1989,varF4e);
Function1(Func1,Func2,Func3,Func4,1989,1989,pvarF4e,1989,Func2,1989,1989,1989);
// 定义 函数指针类型 变量
pFunc1 pF1=Func1;
pFunc2 pF2=Func2;
pFunc3 pF3;
// 使用 函数指针类型 变量
pF1();
pF2(1989,1989);
pF3(0000,1989);
// 简化Function1()
CombinationStruct com;
com.__f1=NULL;
com._f2a=1989;
com._f2b=1989;
com._f3a=pvarF4e;
com._f3b=1989;
com._f4a=Func2;
com._f4c=1989;
com._f4d=1989;
com._f4e=1989;
Function2(Func1,Func2,Func3,Func4,com);
}
int Func1()
{
return 100;
}
int Func2(int a,int b)
{
return (a+b);
}
int* Func3(int* pa,int b)
{
pa=&b;
return pa;
}
int Func4(int (*pFunc2_)(int a,int b),int c,int d,int e)
{
e=pFunc2_(c,d);
return e;
}
void Function1(pFunc1 F1,pFunc2 F2,pFunc3 F3,pFunc4 F4,int f2a,int f2b,int* f3a,int f3b,pFunc2 f4a,int f4c,int f4d,int f4e)
{
int _fRet1=F1();
int _fRet2=F2(f2a,f2b);
int* _fRet3=F3(f3a,f3b);
int _fRet4=F4(f4a,f4c,f4d,f4e);
}
void Function2(pFunc1 F1,pFunc2 F2,pFunc3 F3,pFunc4 F4,CombinationStruct com)
{
int _fRet1=F1();
int _fRet2=F2(com._f2a,com._f2b);
int* _fRet3=F3(com._f3a,com._f3b);
int _fRet4=F4(com._f4a,com._f4c,com._f4d,com._f4e);
}
以上代码只是一个框框,函数并没有实际的使用意义,下面给一个四则运算的实际使用例子
// 定义(返回函数的指针的)函数
//
#include<stdio.h>
// 说的有点拗口。多读几遍应该就差不多了,表达能力有限
// 以下是(定义ReturnFuncPointerFunction(char op)函数所返回的函数指针的)函数定义
// 返回的函数指针suo代表的函数原型的共同点 都是具有两个int型参数,返回值为int型
// 以下四个函数都具备这样的条件
int add(int a, int b);
int sub(int a, int b);
int mul(int a, int b);
int div(int a, int b);
// 定义一个 返回函数指针的函数
int (*ReturnFuncPointerFunction(char op)) (int, int);
// 普通函数
int calc(int a, int b, char op);
void main()
{
int a = 100, b = 20;
printf("calc(%d, %d, %c) = %d\n", a, b, '+', calc(a, b, '+'));
printf("calc(%d, %d, %c) = %d\n", a, b, '-', calc(a, b, '-'));
printf("calc(%d, %d, %c) = %d\n", a, b, '*', calc(a, b, '*'));
printf("calc(%d, %d, %c) = %d\n", a, b, '/', calc(a, b, '/'));
}
// ReturnFuncPointerFunction为函数,它的参数是 op(操作符),
// 返回值为一个拥有 两个int参数、返回类型为int 的函数指针
// 它的作用是根据操作符返回相应函数的地址
// 注意ReturnFuncPointerFunction仅仅是本定义函数的函数名称,不是返回函数的函数指针名称
// 一般我们所见到的返回值类型都是 ElemType或者ElemType*这样的,但是本函数的返回类型是
// 这样的 int (*) (int, int)
int (*ReturnFuncPointerFunction(char op)) (int, int)
{
switch (op)
{
case '+': return add; // 返回函数的地址
case '-': return sub; // 返回函数的地址
case '*': return mul; // 返回函数的地址
case '/': return div; // 返回函数的地址
default : return NULL;
}
return NULL;
}
int calc(int a, int b, char op)
{
// 定义(返回函数的)函数指针;注意与定义(返回函数指针的)函数的区别
int (*pArithmeticFunctionPointer)(int, int) = ReturnFuncPointerFunction(op);
if (pArithmeticFunctionPointer)
{
//根据上一步得到的函数的地址调用相应函数,并返回结果
return pArithmeticFunctionPointer(a, b);
}
else
{
return -1;
}
}
// 加法函数定义
int add(int a, int b){ return a + b;}
// 减法函数定义
int sub(int a, int b){ return a - b;}
// 乘法函数定义
int mul(int a, int b){ return a * b;}
// 除法函数定义
int div(int a, int b){ return b? a/b : -1;}
程序需要反复的调试,观察,理解,再理解,由于上面的代码没有个性的着色,所以得想想办法,如下
就到这里吧,我在整理这些内容是为什么会想到钩子函数和__stdcall这些东西呢?为什么呢?