函数名与数组名的区别:
数组a 与&a值一样,但是类型不一样;但是函数名和函数取地址是一样的:
数组名的取地址和数组名结果一样,但是类型不一样;
变量在定义的时候就分配空间;
函数名字+()就叫函数的调用;
但是在C++中,成员函数用指针函数调用的时候,必须要加&;普通函数函数指针的调用不必加&;
void (*p)(); //函数指针变量;
void f(); 中 f与&f都一样是函数的入口地址;
p=f; //OK; //若是成员函数就不行;
p=&f;//OK;
typedef void (*pp)(); //这里pp是一种类型,可以定义其他的变量;
pp p;
p=f; //OK;//若是成员函数就不行;
p=&f;//OK;
p(); //OK //函数的调用;
(*p)();//OK
代码示例:
#include <stdio.h>
void fun();
void fun1(int);
void fun2(int a,int b);
void pfun(void (*pp)(int ,int ));
int main()
{
void (*p)();
void (*p1)(int);
//p是一个指针,指向的是一个函数,函数里没有参数,返回值是void;
fun(); //函数调用;
p=fun;
p(); //函数调用;
printf("%p\n",fun);//00401005
p=&fun;
(*p)();
printf("%p\n",&fun);//00401005
//函数的地址;函数的名字和函数取地址都是一个东西,并且类型也一样;
p1=&fun1; //函数名就是该函数的地址;
(*p1)(111); //带参数的函数指针;
pfun(fun2); //参数是函数指针的函数;
return 0;
}
void pfun(void (*pp)(int,int )) //参数函数指针的函数,非常方便,可以任意的调用函数;
{
(*pp)(11,22);
}
void fun()
{
printf("hello!!\n");
}
void fun1(int a )
{
printf("fun1:%d !!\n",a);
}
void fun2(int a,int b )
{
printf("fun2:%d--%d!!\n",a,b);
}
下面来看一下比较复杂的指针函数:
void (* fun1( void (*pFun)() ,char *p ) )( int a, int b)
看一下这个函数,我们知道()的优先级最高,所以运行从左到右一次进行;
乍一看,好像挺复杂,其实不用担心,我们可以层层来拨开它,看它的庐山真面目,到底是个什么结构???其实非常简单!方法就是一步一步来!!!
首先看fun1左边是一个括号,代表是一个函数,那么括号里的东西就是它的参数,中间有,号隔开,说明有2个参数 void (*pFun)()和char *p ;接着分析这2个参数首先可以看到pFun是一个指针,是一个指向函数的指针,该函数返回类型为void;另外一个参数就是p,类型是char *;参数就分析完了;
因为fun1是函数,,那么函数还有返回值,返回值是void (* )( int a, int b) ,该返回类型是一个指针,是一个指向函数的指针,该函数有两个参数,一个int a,一个是int b;函数的返回值是void;
打卡手工,这个函数就分析完了!
在整理一遍,fun1是一个函数,该函数有2个参数都是指针,第一个指针指向一个函数,该函数没有参数,返回值为void,第二个参数是char *p;fun1这个函数的返回值是一个指针,该指针指向一个函数,该函数有两个int类型的参数,返回值为void!
完事儿了,分析完了!!还可以吧,,应该不是很复杂,只需要知道优先级,一步步的解剖它!不用怕!!!
下面的事儿就是简化它:
我们可以定义几个函数指针,让着个函数看起来简单点儿:
typedef void (*FNU2)();
typedef void (*FNU3)(int a,int b);
FUN3 fun1(FUN2,char *p);//这就是简化完的函数,非常easy和直观!