定义返回函数指针(地址)的函数

其实函数指针和普通类型的指针没什么区别,只不过从代码的表现形式上略有差异罢了,回顾一下,下面定义两个在普通不过的”变量“,仔细推敲以下他们的区别。(插几句,现在所做的工作虽谈不上是科研,呵呵,和人家比不了,通俗定义可以叫工科男吧,以前做事貌似从未对做过的学问或者工作仔细推敲,但现在不知道什么时候进化到这个状态)

// 定义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这些东西呢?为什么呢?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值