函数的指针和指针函数

本文详细介绍了函数指针和指针函数的概念与应用,包括指针函数的定义和用途,函数指针的声明及赋值方法,以及回调函数的原理。此外,还探讨了如何利用函数指针实现函数的多态性,以避免嵌套调用带来的问题。文章以实际例子阐述了这些概念,有助于读者深入理解函数指针的使用。
摘要由CSDN通过智能技术生成

1. 指针函数

       指针函数是指带指针的函数,即本质是一个函数。函数都有返回类型(如果不返回值,则为无值型),只不过指针函数返回类型是某一类型的指针。也就是说指针函数一定有“函数返回值”,而且,函数的返回值必须用同类型的指针变量来接收。其定义格式如下:

        返回类型标识符 *函数名称(形式参数表)

        {函数体}

        说明:返回类型可以是任何基本类型和复合类型。返回指针的函数的用途十分广泛。事实上,每一个函数,即使它不带有返回某种类型的指针,它本身都有一个入口地址,该地址相当于一个指针。比如函数返回一个整型值,实际上也相当于返回一个指针变量的值,不过这时的变量是函数本身而已,而整个函数相当于一个“变量”。


2. 函数指针

函数指针是指向函数的指针变量,因而“函数指针”本身首先应该是指针变量,只不过是指向函数的指针变量。有了函数指针后,可以用该指针变量调用函数。其定义格式如下:

函数指针的声明方法为:

返回值类型 ( * 指针变量名) ([形参列表]);

注1:"返回值类型"说明函数的返回类型,"(指针变量名 )"中的括号不能省,括号改变了运算符的优先级。若省略整体则成为一个函数说明,说明了一个返回的数据类型是指针的函数,后面的"形参列表"表示指针变量指向的函数所带的参数列表。例如:

int func(int x); /* 声明一个函数 */

int (*f) (int x); /* 声明一个函数指针 */

f=func; /* 将func函数的首地址赋给指针f */

或者使用下面的方法将函数地址赋给函数指针:

f = &func;

赋值时函数func不带括号,也不带参数,由于func代表函数的首地址,因此经过赋值以后,指针f就指向函数func(x)的代码的首地址。

注2:函数括号中的形参可有可无,视情况而定


3. 回调函数

        介绍回调函数前先讲一个故事,整理了网友的解释并稍加修改,故事如下:

        一天诸葛亮让赵子龙押送东西到B城,并给了他三个不同颜色的锦囊,告诉他,“遇到危险的时候,根据危险的程度打开不同的锦囊”,这里面就包含了主函数和回调函数。

       说明:诸葛亮为程序员,赵子龙为主函数,锦囊为回调函数,遇到危险表明程序执行到了回调函数处,所以主函数和回调函数都是由程序员写的,只是在程序的运行过程中,才能确定具体的回调函数。


        普通调用:你无须知道函数的具体实现过程,只需要知道它能完成什么样的功能,只管调用即可(可以为系统函数也可以为自己定义的函数)。

        回调函数:不止要知道函数的调用,还需要实现函数的功能(也可以理解为系统调用自己的定义的函数)。


代码详见:http://blog.csdn.net/zgrjkflmkyc/article/details/9198519


4. 函数的“多态”

在函数的实际调用中,有可能会循环调用不同的函数,来实现功能的切换,例如界面函数的切换。

一般的解决方法是通过函数的嵌套调用来完成,这样有一个弊端,就是容易造成死循环,导致无法跳回主函数。

接下来我们采用函数指针来实现函数的调用:

#include "ui.h"

/* 函数指针,pUI[]数组中保存的是函数名,并非函数(Exit_UI()) */
int (*pUI[]) () = {	&Exit_UI, 		
					&LogIn_UI, 
					&Register_UI,
					&User_UI,
					&Main_UI};

int main()
{
	int index = S_MAIN;
	while( index != X_END)
		index = pUI[index]();
	return 0;
}#ifndef __UI_H__
#define __UI_H__

#include "../inc/logic.h"

/*------- 变量声明区 --------*/
//枚举的顺序要与函数指针数组的顺序保持一致
enum{				//界面编号
	S_EXIT,			//退出界面
	S_LOGIN,		//登录
	S_REGISTER,		//注册
	S_USER,			//用户
	S_MAIN,			//主界面
	X_END			//退出系统
};

/*------- 函数声明区 --------*/
int Main_UI();			//主界面
int Register_UI();		//注册界面
int LogIn_UI();			//登陆界面
int User_UI();			//用户界面
int Exit_UI();			//退出界面

#endif#include "ui.h"

int Main_UI()
{
	int iChoice = 0;
	system("clear");
	STARTLINE;
	TITELLINE;
	printf("\t\t\t|----------      1. 登录       ----------|\n");
	printf("\t\t\t|----------      2. 注册       ----------|\n");
	printf("\t\t\t|----------      0. 退出       ----------|\n");
	ENDLINE;
	printf("\t\t\t请输入相应的序号:");
	scanf("%d", &iChoice);
	while(getchar() != '\n');
	
	if( 0 != (iChoice % 3))
		……
	
	return (iChoice % 3);
}
/*	注册界面	*/
int Register_UI()
{
	/* 函数体 */
	……
	if( …… )
		User_Register(cfd);		//注册用户
	……
	return S_MAIN;
}
/*	登陆界面	*/
int LogIn_UI()
{
    /* 函数体 */
	……
	if( …… )
		return S_USER;		//进入用户界面
	……
	return S_MAIN;
}
/*	用户界面	*/
int User_UI()
{
    /* 函数体 */
	……
	return S_USER;
}
/*	退出界面	*/
int Exit_UI()
{
	/* 函数体 */
	……
	return X_END;
}


<<< 返回博客架构



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值