函数指针与指针函数

函数指针

定义:函数指针本质是指针,它是函数的指针(定义一个指针变量,变量中存储了函数的地址)。 函数都有一个入口地址,所谓指向函数的指针,就是指向函数的入口地址。这里函数名就代表入口 地址。

函数指针存在的意义:

1. 让函数多了一种 调用方式

2. 函数指针作为形参,可以形式调用(回调函数)

定义格式:

        返回值类型(*变量名)(形式参数列表);

举例:

        int (*p) (int a,int b);

函数指针的初始化

1. 定义同时赋值

// 得先有函数,才能定义这个函数的指针
int fun(int a,int b){..}
// 定义函数指针并给它赋值
int (*p) (int a,int b) = fun;// fun不能跟()

2. 先定义后赋值

// 得先有函数,才能定义这个函数的指针
float fun(int a,double b,char c){..}
// 先定义函数指针
float (*p) (int a,double b,char c);
// 赋值
p = fun;

总结:

1. 函数指针指向的函数要和函数指针定义的返回值类型,形参列表对应,否则编译报错

2. 函数指针是指针,但不能指针运算,如p++等,没有实际意义。

3. 函数指针作为形参,可以形成回调(回调后面讲)。

4. 函数指针作为形参,函数调用时的实参只能是与之对应的函数名,不能带小括号。

5. 函数指针的形参列表中的变量名可以省略。

案例:

/**
* 函数指针:指向函数的指针变量就是函数指针
需求:求a,b两个数的最大值
*/
#include <stdio.h>
int max(int a,int b)
{
if(a > b)
{
return a;
}
return b;
}
int main()
{
int a = 3,b = 2,c;
// 普通函数调用
c = max(a,b);
printf("%d,%d两个数中的最大值是:%d\n",a,b,c);
// 通过指针变量访问它指向的函数
// 创建指针并初始化
int (*p)(int,int) = max;
// 调用函数指针
c = p(a,b);
printf("%d,%d两个数中的最大值是:%d\n",a,b,c);
// 调用函数指针
c = (*p)(a,b);
printf("%d,%d两个数中的最大值是:%d\n",a,b,c);
return 0;
}

指针函数

定义:本质是函数,这个函数的返回值类型是指针,这个函数称为指针函数。

定义格式

指针类型 函数名(形参列表)
{
函数体;
return 指针变量;
}

举例:

int *get(int a)
{
int *b = &a;
// return &a; // 编译报警告
return b;
}

注意:

        在函数中不要直接返回一个局部变量的地址,因为函数调用完毕后,局部变量会被回收,使 得返回的地址就不明确,此时返回的指针就是野指针。

解决方案:

        如果非要访问,可以给这个局部变量添加 static ,可以延长它的生命周期,从二避免野指针 (尽量少用,因为存在内存泄漏)。

案例:

/**
* 指针函数:函数的返回值是指针类型
需求:有若干个学生的成绩(每个学生有4门课程),要求在用户输入学生序号以后,能输出该学生的全部成绩。用
指针函数来实现。
*/
#include <stdio.h>
/* 定义一个函数,传入学生的序号,返回这个学生的所有课程成绩 */
float *search(float (*p)[4],int n)
{
// 定义一个指针,用来接收查询到的某个学生的所有课程
float *pt;
pt = *(p+n);// p[n]
return pt;
}
int main()
{
// 准备所有学生的成绩
float score[][4]={{60,70,80,90},{56,66,76,76},{35,68,90,37}};
int i,m;
float *p;
printf("请输入学生序号(0~2):\n");
scanf("%d",&m);
printf("第%d个学生的成绩:\n",m);
p = search(score,m);// 函数返回值为行的首地址
// 遍历
for(i = 0; i < 4;i++)
printf("%5.2f\t",*(p+i));
printf("\n");
return 0;
}

  • 7
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值