一、概念
函数指针和指针函数是C语言里两个比较绕的概念。但是不仅面试题爱考,实际应用中也比较广泛。很多人因为搞不清这两个概念,干脆就避而远之,我刚接触C语言的时候对这两个概念也比较模糊,特别是当指针函数、函数指针、函数指针变量、函数指针数组放在一块的时候,能把强迫症的人活活逼疯。
其实如果理解了这些概念的本质,是不需要死记硬背的,理解起来也比较容易。
二、函数指针
函数指针的本质是一个指针,该指针的地址指向了一个函数,所以它是指向函数的指针。我们知道,函数的定义是存在于代码段,因此,每个函数在代码段中,也有着自己的入口地址,函数指针就是指向代码段中函数入口地址的指针。
1、如何定义一个函数指针?
void (*p2)();
- 如何表示指针:*
- 如何知道是函数:()
- 函数指针是专用的,格式要求很强(参数类型、个数、返回值),就像数组指针一样。
2、如何给函数指针赋值?
p2 = PrintWelcome; PrintWelcome()为函数,函数指针赋值时()不需要写!!!
函数就是地址,就像数组一样,数组名就是地址!
3、如何通过函数指针调用函数?
- 方法1:直接通过指针名字+();
p2();
- 方法2:取内容 (*指针名字)();
(*p2)();
例:
#include<stdio.h>
int add(int a,int b)
{
return a+b;
}
int main()
{
int (*padd)(int a,int b)
padd = add;
int ret = padd(1,2);
printf("ret = %d\n",ret);
return 0;
}
运行结果:ret = 3
4、为什么要使用函数指针?
当项目比较大,代码变得复杂了以后,函数指针就体现出了其优越性。
举个例子:如果我们要实现数组的排序,我们知道常用的数组排序方法有很多种,比如快速排序、插入排序、冒泡排序、选择排序等。如果不管内部实现,你会发现,除了函数名不一样之外,返回值(包括函数传参都是相同的),这时候如果要调用不同的排序方法,就可以使用函数指针来实现,我们只需要修改函数指针初始化的地方,而不需要去修改每个调用的地方(特别是当调用特别频繁的时候)。
例:有两个整数a和b,由用户输入1,2或3。如输入1,程序就给出a和b中大者,输入2,就给出a和b中小者,输入s,则求a与b之和。
#include<stdio.h>
int add(int x,int y)
{
int z;
z = x + y;
printf("sum = ");
return(z);
}
int min(int x,int y)
{
int z;
if(x < y) z = x;
else z = y;
printf("min = ");
return(z);
}
int max(int x,int y)
{
int z;
if(x > y) z = x;
else z = y;
printf("max = ");
return(z);
}
int fun(int x,int y,int (*P)(int,int))
{
int result;
result = (*p)(x,y); //调用函数指针
printf("%d\n",result);
}
int main()
{
void fun(int x,int y,int (*p)(int,int)); //int (*p)(int,int))为定义函数指针
int a = 34,b = -21,n;
printf("请选择1,2或3:");
scanf("%d",&n);
if(n == 1) fun(a,b,max); //函数赋值,max、min、add为指针指向的函数地址(函数名即为地址)
else if(n == 2) fun(a,b,min);
else if(n == 3) fun(a,b,add);
return 0;
}
运行结果:
(1)选择1,调用max函数
请选择1,2或3:
max = 34
(2)选择2,调用min函数
请选择1,2或3:
min = -21
三、指针函数
函数类型是指函数返回值的类型。在C语言中允许一个函数的返回值是一个指针(即地址),这种返回指针值的函数称为指针型函数,简称指针函数。
指针函数声明:
函数返回值类型 *指针变量名 (函数参数列表);
函数返回值类型* 指针变量名 (函数参数列表);
例:
int *max(int x,int y);
int* max(int x,int y);
指针函数的使用:
char *str = func(s1, s2);//函数返回值是一个指针,即接收端也是一个指针
#include <stdio.h>
#include <string.h>
// 返回两个字符串中较长的一个
char *func(char *str1, char *str2)
{
if(strlen(str1) >= strlen(str2))
{
return str1;
}else
{
return str2;
}
}
int main()
{
char *s1 = "C Language";
char *s2 = "C is very great!";
char *longstr = func(s1, s2);
printf("Long string: %s\n", longstr);
return 0;
}