[转载]嗯,让我们彻底搞懂C/C++函数指针吧(二)

原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://hipercomer.blog.51cto.com/4415661/792301

3.4 函数指针作为参数

如果你已经明白了函数的参数机制,而且完全理解并实践了3.3节的内容,这一节其实是很简单的。只需要在函数的参数列表中,声明一个函数指针类型的参数即可,然后再调用的时候传给它一个实参就可以了。你可以这么想象,就是把函数指针的赋值语句的等号换成了形参和实参结合的模式就行。
下面给一个简单的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

/*
* Author :Choas Lee
* Date :2012-02-28
*/

#include<stdio.h>

float add(float a,float b){return a+b;}

float minus(float a,float b){return a-b;}

float multiply(float a,float b){return a*b;}

float divide(float a,float b){return a/b;}

int pass_func_pointer(float (*pFunction)(float a,float b))

{
float result=pFunction(10.0,12.0);
printf("result=%f\n",result);

}

int main()
{
pass_func_pointer(add);
pass_func_pointer(minus);
pass_func_pointer(multiply);
pass_func_pointer(divide);

return 0;
}

输出结果为:

1
result=22.000000 
result=-2.000000 
result=120.000000 
result=0.833333

3.5 使用函数指针作为返回值

函数指针可以作为返回值。我们先类比的思考一下,如果说整型可以作为返回值,你会怎么声明函数?嗯,应该是下面这个样子的:

int func(){}

整数对应的类型为int。同样再类比以下,如果说整型指针可以作为返回值,你会怎么声明?嗯,这个貌似难度也不大:

int * func(){}

好吧,现在说函数指针如果可以作为返回值,你该怎么声明?首先要保证的一点就是返回的函数指针的类型必须是能够明显的表达在这个函数的声明或者定义形式中的,也就是说在这个形式中,要能够包含函数指针所对应的能够确定函数类型的信息:这个函数类型的返回值类型,这个函数类型的参数个数,这个函数类型的参数类型。,
现在我们在类比一次,如果要返回浮点型指针,那么返回类型应该表达为:

float *

如果要函数指针对应的函数是返回值为浮点型,带有两个参数,两个参数都是浮点型,那么返回类型应该表达为下面的表达形式:

float (*)(float ,float )

嗯,没办法,函数的语义比较复杂,对应的表现就是形式的复杂性了。对于返回为浮点型指针的情况,定义的函数的名称放在“float ”的后面,而对于返回为上面类型的函数指针的话,定义的函数就要放在“()”这个括号中的*的后面了。
所以对于以下形式:

float (* func(char op) ) (float ,float)

其具体含义就是,声明了这样一个函数:

其名称为func,其参数的个数为1个;
其各个参数的类型为:op—char;
其返回变量(函数指针)类型为:float(*)(float,float)

再次强调:函数指针时变量哦。
到了这里之后,我们再来分析一下unix的系统调用函数signal的定义形式:

void (*signal)(int signo,void (*func)(int)))(int);

其具体含义为就是,声明了这样一个函数:

其函数名称为:signal
其参数个数为:2
其各个参数的类型为:signo–int, func— void ()(int)
其返回的变量(函数指针)的类型为:void(
)(int)

上面这个函数比较经典,有一个参数类型为函数指针,返回值还是函数指针。
哦,我的天,如果你一步一步看到这里了,就快大功告成啦。嘿嘿,接下来看一个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
/* 
* Author :Choas Lee
* Date :2012-02-28
*/


#include<stdio.h>

#include<stdlib.h>

#include<string.h>

float add(float a,float b){return a+b;}

float minus(float a,float b){return a-b;}

float multiply(float a,float b){return a*b;}

float divide(float a,float b){return a/b;}



float(* FunctionMap(char op) )(float,float)

{
switch(op)
{
case '+':
return add;

break;

case '-':
return minus;

break;

case '*':
return multiply;

break;

case '\\':
return divide;

break;

default:
exit(1);

}
}



int main()
{


float a=10,b=5;
char ops[]={'+','-','*','\\'};
int len=strlen(ops);
int i=0;
float (*returned_function_pointer)(float,float);

for(i=0;i<len;i++)
{

returned_function_pointer=FunctionMap(ops[i]);
printf("the result caculated by the operator %c is %f\n",ops[i],returned_function_pointer(a,b));

}

return 0;

}

// 计算的结果为:

1
the result caculated by the operator + is 15.000000 
the result caculated by the operator - is 5.000000 
the result caculated by the operator * is 50.000000 
the result caculated by the operator \ is 2.000000

为什么还提示我大于80000字符?清除冗余格式??哼~ 不好意思啊,详见下一篇