2015/2/13,在VC++6.0下测试
最初只是看到有同学在使用这个奇怪的语法,认真学习了一下,原来函数名即使一个函数的地址。
例如下面几行代码:
#include <iostream>
using namespace std;
void say()
{
cout<<"hello"<<endl;
}
int main()
{
void (*sayPtr)()=say; //将函数的地址给sayPtr
(*sayPtr)(); //sayPtr即是函数的地址,()为调用函数
sayPtr(); //和上一句是一样的
(*say)(); //自己尝试了一下,果然函数名是地址,用*解引用就成功调用了函数
return 0;
}
结果:
7
5
10
Press any key to continue
上面测试的是无参的函数,下面有参的函数
void print(int x,int y)
{
int z=x+y;
cout<<z<<endl;
}
例如这个简单的函数,在main函数总调用
void (*printPtr)(int,int)=print;
(*printPtr)(2,5);
printPtr(3,2);
(*print)(3,7);
结果:
7
5
10
Press any key to continue
与无参函数相同,只是多了参数。
有返回值的函数:
int (*addPtr)(int,int)=add;
cout<<(*add)(3,5)<<endl;
cout<<(*addPtr)(3,2)<<endl;
cout<<addPtr(3,3)<<endl;
结果:
8
5
6
Press any key to continue
与以上的例子一样只是多了返回值。
将函数指针作为参数:
int add(int x,int y)
{
return x+y;
}
int sub(int x,int y)
{
return x-y;
}
int domath(int (*mathop)(int,int),int x,int y)
{
return mathop(x,y);
}
int main()
{
cout<<domath(add,5,6)<<endl;
cout<<domath(sub,12,3)<<endl;
return 0;
}
结果:
11
9
Press any key to continue
只是在定义domath函数的时候讲参数中一个设为函数的地址。
在此验证了函数名是函数的地址,而且能代替函数指针使用。
在此贴上一个虽然糟糕却能很好说明函数指针的程序:
#include <stdio.h>
// 函数原型
void add(char *name, int x, int y);
// 加法 x + y
void add(char *name, int x, int y) {
printf("%s gives: %d\n", name, x + y);
}
// main函数调用
int main() {
// 一些糟糕的函数指针赋值
void (*add1Ptr)(char*, int, int) = add;
void (*add2Ptr)(char*, int, int) = *add;
void (*add3Ptr)(char*, int, int) = &add;
void (*add4Ptr)(char*, int, int) = **add;
void (*add5Ptr)(char*, int, int) = ***add;
// 仍然能够正常运行
(*add1Ptr)("add1Ptr", 10, 2);
(*add2Ptr)("add2Ptr", 10, 2);
(*add3Ptr)("add3Ptr", 10, 2);
(*add4Ptr)("add4Ptr", 10, 2);
(*add5Ptr)("add5Ptr", 10, 2);
// 当然,这也能运行
add1Ptr("add1PtrFunc", 10, 2);
add2Ptr("add2PtrFunc", 10, 2);
add3Ptr("add3PtrFunc", 10, 2);
add4Ptr("add4PtrFunc", 10, 2);
add5Ptr("add5PtrFunc", 10, 2);
}
总结:
函数名会被隐式的转换为一个指针,就像是数组名一样,因此函数指针都可以用函数名来表示,而且在*和&符号在数组名前面几乎都是多余的。
另屏蔽一段代码可以用宏,
#if 0
#endif。非常有用的其实。