首页 > 其他分享 >C语言(函数指针与指针函数)

C语言(函数指针与指针函数)

时间:2024-12-11 15:59:30浏览次数:11  
标签:return 函数 int C语言 printf 函数指针 指针

函数指针

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

  1. 让函数多了一种调用方式
  2. 函数指针作为形参,可以形式调用(回调函数)

定义格式:

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

举例:

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

函数指针的初始化:

  1. 定义的同时赋值
 // 函数指针需要依赖于函数,先有函数,再有指针
// 定义一个普通的函数
int add(int a,int b){ return a + b;}
 // 定义一个函数指针,并给他赋值
// 通过以下代码我们发现:函数指针的返回类型和依赖函数的返回类型一致,函数指针的参数个数类型和依赖函
数一致
int (*p)(int a,int b) = add;// 赋值一定要注意:函数不能带有()
  1. 先定义后赋值
 // 定义一个普通的函数
int add(int a,int b){ return a + b;}
 // 定义一个函数指针
// int (*p)(int a,int b);
 int (*p)(int,int);  // 一般写作这种
// 给函数指针赋值
p = add;

注意:

  1. 函数指针指向的函数要和函数指针定义的返回值类型,形参列表对应,否则编译报错
  2. 函数指针时指针,但不能指针运算,如p++等,没有实际意义
  3. 函数指针作为形参,可以形成回调
  4. 函数指针作为形参,函数调用时的实参只能是与之对应的函数名,不能带小括号()
  5. 函数指针的形参列表中的变量名可以省略

案例

#include <stdio.h>
 /**
 * 定义一个函数指针
*/ 
int max(int a,int b)
 {
 if(a > b)
 return a;
 return b;
 }
 int main(int argc,char *argv[])
 {
 // 定义测试数据
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;
 }

回调函数(了解)

概念

回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。

为什么要用回调函数

因为可以把调用者与被调用者分开,所以调用者不关心谁是被调用者。它只需知道存在一个具有特定原型和限制条件的被调用函数。
简而言之,回调函数就是允许用户把需要调用的方法的指针作为参数传递给一个函数,以便该函数在处理相似事件的时候可以灵活的使用不同的方法。

实现

 #include <stdio.h>
 /**
 * 回调函数1
 */
 int callback_1(int a)
 {
 printf("hello,this is callback_1:a=%d\n",a);
 return 0;
 }
 /**
 * 回调函数2
 */ 
int callback_2(int b)
 {
 printf("hello,this is callback_2:b=%d\n",b);
  }
 /**
 * 实现回调函数
*/ 
int handle(int x,int (*callback)(int))
 {
 printf("开始执行!\n");
 callback(x);
 printf("执行结束!\n");
 }
 int main(int argc,char *argv[])
 {
 handle(100,callback_1);
 handle(200,callback_2);
 return 0;
 }

指针函数

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

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

举例:

 // int *get(int a)
 int* get(int a)
 {
 int *b = &a;
 return b;
 }
 int main()
 {
 int *a = get(5);
 printf("%d\n",*a);
 }

注意:
在函数中不要直接返回一个局部变量的地址,因为函数调用完毕后,局部变量会被回收,使得返回的地址就不明确,此时返回的指针就是野指针。
解决方案:
如果非要访问,可以给这个局部变量添加static ,可以延长它的生命周期,从而避免野指针(尽量少用,因为存在内存泄漏)

案例

#include <stdio.h>
 /**
 * 定义一个函数,传入学生的序号,返回这个学生的所有课程成绩
* @param p 二维数组
* @param n 学生索引(二维数组中行号)
* @return 学生成绩(行号对应的列数组)
*/ 
float* search(float (*p)[4],int n) 
{
 // 定义一个指针,用来接收查询到的某个学生的所有课程
float *pt;
 pt = *(p+n);// *(p+n),*p[n],p[n]
  return pt;
 }
 int main(int argc,char *argv[])
 {
 // 准备一个二维数组
float score[][4] = {{60,70,80,89},{55,66,77,88},{90,89,90,91}};
 int m;
 float *p;
 printf("请输入学生序号(0~2):\n");
 scanf("%d",&m);
 printf("第%d个学生的成绩:\n",m);
 // 用来接收某个学生的所有成绩
p = search(score,m);
 // 遍历成绩
for(int i = 0;i < 4;i++)
 printf("%5.2f\t",*(p+i));
 printf("\n");
 }

标签:return,函数,int,C语言,printf,函数指针,指针
From: https://blog.csdn.net/weixin_69851948/article/details/144403064

相关文章

  • C语言(指针数组和数组指针)
    变量指针与指针变量指针变量指向数组通过指针引用数组元素引用一个数组元素,可以用:下标法:如a[i]形式。指针法:如*(a+i)*(p+i)。其中a是数组名,p是指向数组元素的指针变量,其初值:p=a;案例需求:有一个整型数组a,有10个元素。输出数组中的全部元素。分析:要输出各元素的值,有三......
  • (nice!!!)(LeetCode 热题 100) 76. 最小覆盖子串(哈希表、滑动窗口、双指针)
    题目:76.最小覆盖子串思路:用哈希表来记录字符串t中字符出现的情况。然后用双指针来实现滑动窗口,找到最小的字符串即可。时间复杂度为0(m+n),细节看注释。classSolution{public:stringminWindow(strings,stringt){ //哈希表unordered_map<char......
  • Go指针进阶:从入门到被虐,90%开发者都踩过这些坑
    Go指针进阶:从入门到被虐,90%开发者都踩过这些坑!原创 瀛洲在线编程之道 黑客编程之道  2024年11月17日21:10 吉林 听全文黑客编程之道分享黑客编程技术,Go、Python、Rust、Java等编程技术166篇原创内容公众号指针是Go语言中最强大但也最容易出错的特......
  • C语言:define定义常量和定义宏(详解)
    本篇博客给大家带来的是#define定义常量和#define定义宏的方法......
  • cpp智能指针
      普通指针的不足new和new[]的内存需要用delete和deletel]释放。程序员的主观失误,忘了或漏了释放。程序员也不确定何时释放。普通指针的释放类内的指针,在析构函数中释放。C++内置数据类型,如何释放?new出来的类,本身如何释放?C++11新增三个智能指针类型uniqu......
  • 基于Objective-C和C语言的蜂巢爆料组件设计源码-Z5yUlJ1u
    基于Objective-C和C语言的蜂巢爆料组件设计源码地址该项目是基于Objective-C和C语言的蜂巢爆料组件设计源码,包含312个文件,其中包括292个PNG图片文件、4个头文件(.h)、3个属性列表文件(.plist)、1个模块映射文件(modulemap)以及一系列框架和签名文件。该组件适用于需要高效信息收集......
  • 善于运用指针--通过指针引用数组
    一个数组包含若干个元素,每个元素在内存中占用储存单元,它们都有相应的地址,指针变量能指向变量,也可以指向地址。所谓数组元素的地址,也就是数组元素的指针。文章目录前言一、在引用数组元素时指针的运算二、通过指针引用数组元素三、用数组名作函数参数1用指针打印数组2.指......
  • #学习C语言选择结构和循环结构的感悟
     在深入学习C语言的过程中,我逐渐领略到了选择结构和循环结构的重要性。这两种结构不仅是编程语言的基础,更是我们解决问题的重要工具。它们如同一座座桥梁,连接着我们的思维和计算机之间的交互,使我们能够用代码来实现复杂的逻辑和功能。 **一、选择结构——决策的智慧** ......
  • C语言指针
    1.指针的相关概念指针:就是一个指针变量,指向了某个变量的内存地址内存:指的是内存空间,内存中多个存储单元,每个内存存储单元就是一个小块空间,有自己的编号,这个编号就是地址,每个内存存储单元就是1个字节,8个位。取地址符号:&取值符号:*格式占位符:%p,显示内存......
  • C语言中实现归并排序(Merge Sort)
    归并排序(MergeSort)是一种基于分治法(DivideandConquer)的高效排序算法,具有稳定性和O(nlogn)的时间复杂度,特别适用于处理大规模数据。基本原理归并排序通过以下步骤实现排序:分割(Divide):递归地将数组分成两半,直到每个子数组仅包含一个元素。合并(Conquer):将两个有序子数组合......