注:()的优先级高于*。
一.指针函数
1.定义:
指针函数实质是一个函数,与普通的函数相同,但是普通函数都有返回类型(如果不返回值,则为无值型),指针函数返回类型是某一类型的指针。
2.一般形式:
类型名 *函数名(函数传参列表);
例如:
int* fun(int a, int b);
int * fun(int a, int b);
int *fun(int a, int b);
//都定义了一个指针函数,具体的写法因人而异。
该代码定义了一个指针函数,它的返回值类型为 int * 类型。
3.示例:
#include <stdio.h>
char *strcpy(char *s1, char *s2) {
char *p = s1; //用p保存s1接受来的实参字符数组的首地址
while (*s1++ = *s2++); //当s2指到‘\0’时,先赋值完成后循环结束
return p; //通过函数名返回指针值
}
int main(void) {
char s[20];
printf("%s\n", strcpy(s, "Welcome to you!")); //输出返回值指向的内容
return 0;
}
输出结果:
Welcome to you!
二.函数指针
1.定义:
函数指针的本质是一个指针变量,该指针指向这个函数。简而言之,函数指针就是指向函数的指针。
2.一般类型:
类型名 (*指针变量名)(函数传参列表);
例如:
int (*fun)(int a, int b);
该代码定义了一个指向函数的指针,指针名为 fun,指向的函数类型为 int 型,且传递两个 int 类型的变量。
3.说明:
①定义指向函数的指针变量,并不意味着这个指针变量可以指向任何函数,它只能指向在定义时指定的类型的函数。如:
“int (*p)(int ,int);”表示指针变量p可以指向函数返回值为整型且有两个整型参数的函数。在程序中把哪一个函数(该函数的值时整型的且有两个整型的参数)的地址赋给它,它就指向哪一个函数。
在一个程序中,一个指针变量可以先后指向同类型的不同函数。
②如果要用指针调用函数,必须先使指针变量指向该函数。如:
p = max;
这就把max函数的入口地址赋给了指针变量p。
③在给函数指针变量赋值时,只须给出函数名而不必给出参数。例如:
p = max; //将函数的入口地址赋给p
因为是将函数入口的地址赋给p,而不牵涉实参与形参的结合问题。如果写成
p = max(a, b);
就错了。p = max(a, b)的作用是将调用max函数所得到的函数值赋给p,而不是将函数入口地址赋给p。
④用函数指针变量调用函数时,只需将(*p)代替函数名即可(p为指针变量名),在(*p)之后的括号中根据需要写上实参。 例如:
c = (*p)(a, b);
表示“调用由p指向的函数,实参为a,b。得到的函数值赋给c”。
请注意函数返回值的类型。从指针变量p的定义中可以知道,函数的返回值应是整型的,因此将其值赋给整型变量c是合法的。
⑤对指向函数的指针变量不能进行算数运算,如:p + n, p++, p–等运算是无意义的。
⑥用函数名调用函数,只能调用所指定的一个函数,而通过指针变量调用函数比较灵活,可以根据不同情况先后调用不同的函数。
4.示例:
#include <stdio.h>
#include <stdlib.h>
int add(int x, int y) {
return x + y;
}
int sub(int x, int y) {
return x - y;
}
int (*f)(int x, int y); //函数指针
int main(void) {
f = &add;
printf("%d\n", (*f)(1, 2));
f = ⊂
printf("%d\n",(*f)(1, 2));
return 0;
}
5.回调函数(用指向函数的指针做函数参数)
指向函数的指针变量的一个重要用途是把函数的入口地址作为参数传递到其它函数。
指向函数的指针可以作为函数参数,把函数的入口地址传递给形参,这样就能够在被调用的函数中使用形参。它的原理可以简述如下:
有一个函数(假设函数名为fun),它有两个形参(x1和x2),定义x1和x2为指向函数的指针变量。在调用函数fun时,实参为两个函数名f1和f2,给形参传递的时函数f1和f2的入口地址。这样在函数fun中就可以调用f1和f2函数了。
例如:
void fun(int (*x1)(int), int(*x2)(int, int)) {
//定义fun函数,形参是指向函数的指针变量
int a, b, i = 3, j = 5;
a = (*x1)(i); //调用f1函数,i是实参
b = (*x2)(i, j); //调用f2函数,i,j是实参
}
优点:
灵活性高。 调用的函数可以不固定,只要在每次调用fun函数时给出不同的函数名作为实参即可,fun函数不必做任何修改。
示例:
求自然数1~n的奇数或偶数和,用指向函数的指针变量作为函数的参数。
#include <stdio.h>
int evensum(int n) {
int i, sum = 0;
for (i = 2; i <= n; i += 2) {
sum += i;
}
return sum;
} //求自然数1~n中偶数的和
int oddsum(int n) {
int i ,sum = 0;
for (i = 1; i <= n; i += 2) {
sum += i;
}
return sum;
} //求自然数1~n中奇数的和
int result(int n, int (*p)(int)) {
//参数p为指向函数的指针变量
int sum;
sum = (*p)(n); //调用p所指向的函数
return sum;
}
int main(void) {
int n, sum, flag;
printf("input n:\n");
scanf("%d", &n);
printf("input flag(0 or 1):\n");//输入0表示求偶数和,1表示求奇数和
scanf("%d", &flag);
if (flag == 1) {
sum = result(n, oddsum);
} else {
sum = result(n, evensum);
}
sum = (*p)(n);
printf("sum = %d\n", sum);
return 0;
}
三.指针函数和函数指针的区别
主体 | 需求 | 基本定义形式 | |
---|---|---|---|
指针函数 | 函数 | 返回类型为指针 | 类型名 *函数名(函数传参列表); |
函数指针 | 指针 | 指向一个函数 | 类型名 (*指针变量名)(函数传参列表); |
转载:https://blog.csdn.net/m0_55124878/article/details/115643131