函数指针( 是指针)
1.定义
如果在程序中定义了一个函数,在编译时,编译器为函数代码分配了一段存储空间,这段存储空间的起始地址(也就是函数的入口地址),称为这个指向这个函数的指针,也就是函数指针。
我们可以定义一个指向函数的指针变量,来存储这个函数的起始地址。此时,该指针指向该函数
2.语法
返回值类型 (*变量名)(参数列表)
int (*p)(int,int)
首先p要和*号结合,但是圆括号的优先级比较高,如果不用括号把*p括起来,那么语法上就有了错误,举个例子:int * p(int,int)
编译器会认为p和括号先结合,如果p和括号先结合,那么就成了一个函数,表示的意思是函数的返回值是int*类型,参数是两个int类型的数据,所以我们要用括号把*p括起来。
返回值类型是指向函数的返回值类型,参数列表式指向函数的参数列表。
一个函数指针可以先后指向同类型的不同函数。
赋值:p=func func为函数名,该语句将func()的入口地址给了p
3.通过函数指针调用函数
和用函数名调用的唯一区别是:函数名--------->(*p)
int func(int a,int b)
{
return a+b;
}
void main()
{
int result;
int (*p)(int,int);//定义函数指针变量p
p=func;
result=(*p)(2,5);
return 0;
}
函数指针数组(是数组)
1.定义
是用来存放函数指针的数组。
2.语法
int (*p[4])(int ,int )
首先这是一个数组,所以p要和[]先结合,我们拿掉数组名后剩下的就是数组的元素类型
也就是: int (*)(int int) 函数指针
3.应用(实现计算器)
在实际应用中,可以减少代码量
#include<stdio.h>
int Add(int x, int y)
{
return x+y;
}
int Sub(int x, int y)
{
return x-y;
}
int Mul(int x, int y)
{
return x*y;
}
int Div(int x, int y)
{
return x/y;
}
void menu()
{
printf("******************************\n");
printf("** 1. add 2. sub **\n");
printf("** 3. mul 4. div **\n");
printf("** 0.exit **\n");
printf("******************************\n");
}
void calc(int (*pfun)(int, int))
{
int x = 0;
int y = 0;
int ret = 0;
printf("请输入要进行计算的值:");
scanf("%d%d", &x, &y);
ret = pfun(x, y);
printf("ret = %d\n", ret);
}
int main()
{
int input = 0;
int x = 0;
int y = 0;
int ret = 0;
int (*pfun[5])(int , int) = {0, Add, Sub, Mul, Div};
//创建函数指针的数组,数组中保存的都是返回值为int的函数的指针。
do
{
menu();
printf("请选择:");
scanf("%d", &input);
switch(input)
{
case 1:
calc(pfun[1]);
//通过数组调用函数的指针进而调用函数,可大量节省代码篇幅
break;
case 2:
calc(pfun[2]);
break;
case 3:
calc(pfun[3]);
break;
case 4:
calc(pfun[4]);
break;
case 0:
printf("退出\n");
break;
default:
printf("输入错误,请重新输入\n");
break;
}
}while(input);
return 0;
}
数组指针(是指针)
在这里数组指针是指向数组的指针,其本质为指针指向的对象是数组。
int (* p2)[10]; // 数组指针
p2先与“ * ”构成指针定义,int表示数组内容,[10]表示数组内元素个数。
指针数组(是数组)
当我们在学习指针与数组时总会遇到两个令人容易混淆的概念:数组指针与指针数组。
int * p1 [10]; // 指针数组
p1先与“[ ]”结合构成一个包含10个元素的数组,int*表示的则是数组的内容。