C语言中的函数指针和左右法则

1、一个普通的函数调用例子

//自行包含头文件
void MyFun(int x); //此处的申明也可写成:void MyFun( int ); 
int main(int argc, char* argv[])
{  
    MyFun(10);    //这里是调用MyFun(10);函数    
    return 0;
} 
void MyFun(int x) //这里定义一个MyFun函数
{  
    printf(“%d\n”,x);
}

这个MyFun函数是一个无返回值的函数,它并不完成什么事情,只是一个普通的函数,在主函数中进行调用,主函数调用MyFun函数的书写格式为: MyFun(10);
我们一开始只是从功能上或者说从数学意义上理解MyFun这个函数,知道MyFun函数名代表的是一个功能(或是说一段代码)。但是直到学习了函数指针的概念后,不得不思考函数名到底是什么东西呢??(可能你觉得这没有什么意义,不要着急,继续向下看。)
函数指针变量的申明:就象某一数据变量的内存地址可以存储在相应的指针变量中一样,函数的首地址也可以存储在某个函数指针变量里面,这样,我们就可以通过这个函数指针变量来调用所指向的函数了。
在C系列语言中,任何一个变量,总是要先申明,之后才能使用的,那么,函数指针变量也应该要先申明吧?那又是如何来申明呢?以上面的例子为例,我来申明一个可以指向MyFun函数的函数指针变量FunP,下面就是申明FunP变量的方法:
void (*FunP)(int) ; //也可写成void (*FunP)(int x);
通过上面的申明可知,整个函数指针变量的申明格式如同函数MyFun的申明处一样,只不过——我们把MyFun改成(*FunP)而已,这样就有了一个能指向MyFun函数的指针FunP了。(当然,这个FunP指针变量也可以指向所有其它具有相同参数及返回值的函数)

2、通过函数指针变量调用函数
有了FunP指针变量后,我们就可以对它赋值指向MyFun,然后通过FunP来调用MyFun函数了。看我如何通过FunP指针变量来调用MyFun函数的:

//自行包含头文件
void MyFun(int x); //这个申明也可写成:void MyFun( int );
void (*FunP)(int ); //也可申明成void(*FunP)(int x),但习惯上一般不这样。
int main(int argc, char* argv[])
{  
    MyFun(10);     //这是直接调用MyFun函数  
    FunP=&MyFun;   //将MyFun函数的地址赋给FunP变量  
    (*FunP)(20);   //这是通过函数指针变量FunP来调用MyFun函数的

    return 0;
}
void MyFun(int x)  //这里定义一个MyFun函数
{
    printf(“%d\n”,x);
}

运行上面的例子,通过函数指针可以准确无误的调用MyFun函数。
通过上面的例子,我们就会想——MyFun与FunP的类型关系类似于int 与int 的关系??函数MyFun好像是一个如int的变量(或常量),而FunP则像一个如int 一样的指针变量!!

int i,*pi;
pi=&i;          //与FunP=&MyFun比较

好像可以类似,其实不然,通过函数指针调用函数还有其他的书写格式,来完成同样的事情,如下几种书写格式:
代码之一:

//自行包含头文件
void MyFun(int x); 
void (*FunP)(int );   //申明一个用以指向同样参数,返回值函数的指针变量
int main(int argc, char* argv[])
{  
    MyFun(10);        //这里是调用MyFun(10)函数
    FunP=MyFun;       //将MyFun函数的地址赋给FunP变量
    FunP(20);         //这是通过函数指针变量来调用MyFun函数

    return 0;    
} 
void MyFun(int x) //这里定义一个MyFun函数
{  
    printf(“%d\n”,x);
}

运行这个例子,准确无误的得到与上面例子同样的结果,上面的例子中出现语句:FunP=MyFun; 这就有点糊涂了,这样将MyFun值同赋值给FunP,难道MyFun与FunP是同一数据类型(即如同的int 与int的关系),而不是如同int 与int*的关系了?暂时不解释,先看看下面的代码:
代码之二:

//自行包含头文件
void MyFun(int x); 
void (*FunP)(int );   //申明一个用以指向同样参数,返回值函数的指针变量
int main(int argc, char* argv[])
{  
    MyFun(10);        //这里是调用MyFun(10)函数
    FunP=&MyFun;      //将MyFun函数的地址赋给FunP变量
    FunP(20);         //这是通过函数指针变量来调用MyFun函数  

    return 0;  
} 
void MyFun(int x) //这里定义一个MyFun函数
{  
    printf(“%d\n”,x);
}

代码之三:

//自行包含头文件
void MyFun(int x); 
void (*FunP)(int );   //申明一个用以指向同样参数,返回值函数的指针变量
int main(int argc, char* argv[])
{  
    MyFun(10);        //这里是调用MyFun(10)函数
    FunP=MyFun;       //将MyFun函数的地址赋给FunP变量
    (*FunP)(20);      //这是通过函数指针变量来调用MyFun函数    

    return 0;
} 
void MyFun(int x) //这里定义一个MyFun函数
{  
    printf(“%d\n”,x);
}

将以上两段代码分别运行,得到的结果与前面两个例子运行的结果一致。
还有下面的例子,运行也没有问题吆!!

//自行包含头文件
void MyFun(int x);    //此处的申明也可写成:void MyFun( int ); 
int main(int argc, char* argv[])
{  
    (*MyFun)(10);    //看,函数名MyFun也可以有这样的调用格式    
    return 0;
} 
void MyFun(int x)     //这里定义一个MyFun函数
{  
    printf(“%d\n”,x);
}

你也许第一次见到吧:函数名调用也可以是这样写的啊!(只不过我们平常没有这样书写罢了)
那么,这些又说明了什么呢?可以的得到以下结论:
(1)、其实,MyFun的函数名与FunP函数指针都是一样的,即都是函数指针。MyFun函数名是一个函数指针常量,而FunP是一个函数数指针变量,这是它们的关系。
(2)、但函数名调用如果都得如(*MyFun)(10),这样,那书写与读起来都是不方便和不习惯的。所以C语言的设计者们才会设计成又可允许MyFun(10)这种形式地调用(这样方便多了并与数学中的函数形式一样,不是吗?)
(3)、为统一起见,FunP函数指针变量也可以FunP(10)的形式来调用。
(4)、赋值时,即可FunP=&MyFun形式,也可FunP=MyFun。
上述代码的书写格式,随你的喜好写成什么形式都可以!!
但是有一点需要格外注意,如下:

void MyFun(int);        //不能写成void (*MyFun)(int);
void (*FunP)(int);      //不能写成void FunP(int);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值