C指针之舞——指针探秘之旅(2)

ops/2024/11/25 10:37:36/

❤博客主页:折枝寄北-CSDN博客

❤专栏:C语言学习专栏

在上一篇博客文章:C指针之舞——指针探秘之旅-CSDN博客中,我们学习了字符指针,指针数组,数组指针,数组传参和指针传参等内容,下面进一步学习C语言指针。

1.函数指针数组

函数指针就是一个指针,指针中所保存的地址中的内容是一个函数,同之前说过的数组指针相似,函数指针的定义为:

返回类型  (* 指针名) (函数参数)   //eg: int (*pc) (intx,iny)

与数组指针一样,当定义函数指针的时候,* 需要和指针名打括号相结合,( )的优先级高于 * ,不打括号编译器自动会将 指针名 与( )相结合,如 int * pa (int x,int y) ,这样的话便是一个名为pa的函数,函数参数为 int x,int y,函数的返回类型时 int *

通过一个例子来认识一下函数指针数组:

(*(void (*)())0)();

1.先看 void ( * ) ( )  ,这是一个标准的函数指针,函数返回类型为void,无函数参数
2.再看蓝色括号,该括号的代表强制转换,例如:(float)3 指的是将int类型的3转换为float类型,在这里指的是将int类型的0转换为函数指针类型
3.看蓝色括号前面的 * ,这里是解地址符,指找到地址是0的函数
4.红色的括号包括着地址是0的这个函数(函数指针此时是0),后面再跟着一个绿色的括号,相当于调用函数
所以该代码是一次函数调用,调用的是一个返回类型为void,无函数参数,函数名为0 的一个函数

2.回调函数

定义:回调函数是利用函数指针调⽤的函数,通俗来讲,只要是一个函数参数里面有函数指针,都可以被称为回调函数。

例如:完成一个简易的计算器,要求输入1代表计算加法,2代表计算减法,3代表计算乘法,4代表计算除法,0代表退出计算器,选择1 2 3 4其中一个后输入要计算的两个数字,返回计算结果

当不使用回调函数的代码如下:

#include <stdio.h>
int add(int a, int b)
{return a + b;
}
int sub(int a, int b)
{return a - b;
}
int mul(int a, int b)
{return a * b;
}
int div(int a, int b)
{return a/b;
}
int main()
{int x, y;int input = 0;int ret = 0;do{printf("***********************\n"); printf("* 0:退出 1:add  2:sub *\n");printf("*     3:mul   4.div   *\n");printf("***********************\n");printf("请选择:");scanf("%d", &input);switch (input){case 1:printf("输入操作数:");scanf("%d %d", &x, &y);ret = add(x, y);printf("ret = %d\n", ret);break;case 2:printf("输入操作数:");scanf("%d %d", &x, &y);ret = sub(x, y);printf("ret = %d\n", ret);break;case 3:printf("输入操作数:");scanf("%d %d", &x, &y);ret = mul(x, y);printf("ret = %d\n", ret);break;case 4:printf("输入操作数:");scanf("%d %d", &x, &y);ret = div(x, y);printf("ret = %d\n", ret);break;case 0:printf("退出程序\n");break;default:printf("选择错误\n");break;}} while (input);return 0;
}

可以看到有多个重复的步骤,增加了无意义的工作量,这是我们可以注意到这四个函数(add,sub,mul,div)的函数参数都是两个int类型的变量,返回值也都是int,那么我们就可以使用回调函数来简化代码。

简化代码如下:

#include <stdio.h>
void menu()
{printf("*************************\n");printf("    1:add       2:sub \n");printf("    3:mul       4:div \n");printf("    0:exit \n");printf("*************************\n");
}
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 Callback(int (*pfun)(int,int))
{int x = 0;int y = 0;int ret = 0;printf("请输入两个数字:");scanf("%d %d",&x,&y);ret = pfun(x,y);printf("结果为:%d\n",ret);
}
int main()
{int input = 0;do{menu();printf("请输入你的选择:----->");scanf("%d",&input);switch(input){case 1:Callback(Add);break;case 2:Callback(Sub);break;case 3:Callback(Mul);break;case 4:Callback(Div);break;case 0:printf("退出计算器!");break;	default:break;}}while(input);return 0;
} 


http://www.ppmy.cn/ops/136539.html

相关文章

idea添加版权信息

1、添加Copyright Profiles 打开Settings -> Editor -> Copyright -> Copyright Profiles -> 新增 Copyright (c) 【你的版权信息】 【开始年份】-${today.year}. All rights reserved.如&#xff1a; Copyright (c) by cwp 2024-${today.year}. All rights rese…

链表的介绍与单链表的实现

1.链表的介绍 链表分为单链表与双链表。链表和顺序表一样&#xff0c;均属于顺序表&#xff0c;因此链表的逻辑结构是线性的。链表在内存中的存储方式是不一定连续的&#xff08;因此链表的物理结构不一定是线性的&#xff09;&#xff0c;也不一定是按照顺序存储。 2、节点…

ESP32移植Openharmony外设篇(6)光敏电阻ADC读取

光照传感器 模块简介 产品描述 光敏电阻&#xff08;photoresistor orlight-dependent resistor&#xff0c;后者缩写为LDR&#xff09;是一种基于内光电效应的半导体元件&#xff0c;它的阻值依赖于入射光强的变化 。入射光强增加&#xff0c;光敏电阻的阻值减小&#xff0…

FIFO和LRU算法实现操作系统中主存管理

FIFO&#xff0c;用数组实现 1和2都是使用nextReplace实现新页面位置的更新 1、不精确时间&#xff1a;用ctime输出运行时间都是0.00秒 #include <iostream> #include <iomanip> #include<ctime>//用于计算时间 using namespace std;// 页访问顺序 int pa…

linux下i2c开发与框架源码分析

目录 1 概述 2 I2c子系统框架 3 I2C的使用流程 3.1 在驱动里使用 3.2 在应用层使用 3.3 I2ctool的使用 4 为硬件i2c注册一个适配器 5 i2c子系统源码流程分析 5.1 i2c device与driver绑定过程 5.1.1 Driver的注册与处理 5.1.2 Client device的生成 5.2 I2c的发送与接…

【C++】类(三):类的其它特性

7.3 类的其它特性 本节将继续介绍之前章节当中 Sales_data 没有体现出来的类的特性&#xff0c;包括&#xff1a;类型成员、类的成员的类内初始值、可变数据成员、内联成员函数、从成员函数返回*this、如何定义并使用类类型及友元类等。 7.3.1 类成员再探 这部分定义了一对相…

机器学习入门-Scikit-learn

目录 一.Sklearn基本介绍 二.以鸢尾花数据集为例&#xff0c;理解基础运用 1.导入包 2.加载数据集 3.数据预处理 4.数据集拆分 5.模型训练 6.模型评估 7.模型保存和加载 三.碎碎念 一.Sklearn基本介绍 scikit-learn是一个开源的Python机器学习库&#xff0c;提供了大…

无Linux管理员权限,照样可以安装CUDA

以下演示内容使用CUDA版本为 CUDA11.7 1、官网 官网:CUDA官网下载地址 这里会列出所有的CUDA版本,选择需要的版本即可。 2、查看系统信息 这里分享三个命令,可以查看Linux系统的配置信息,方便下一步下载合适的CUDA版本。 可以根据这些命令输出的系统配置信息选择相应的…