函数指针与指针函数

函数指针:

定义
函数指针是指向函数的指针,其本质是一个指针变量,该指针指向这个函数。即指针存储的地址是一个函数的地址,函数指针就是指向函数的指针。

用途

  1. 函数指针可以作为参数传递给其他函数,用于回调函数(callback)的实现。函数回调本质为函数指针作为函数参数,函数调用时传入函数地址,这使我们的代码变得更加灵活,可复用性更强。
  2. 用于在运行时选择调用哪个函数。

用途一:回调函数

int (*fun)(int x,int y);

用法

int maxValue (int a, int b) {
return a > b ? a : b;
}
int (*p)(int, int) = NULL;  //定义一个与maxValue兼容的指针
p = maxValue;
p(20, 45);  //通过指针调用

注意,为什么函数赋值,不是p = &maxValue;

函数指针是需要把一个函数的地址赋值给它,有两种写法:

 1. fun = &Function;2. fun = Function;

其中第二种看上去和普通的函数调用没啥区别。

用途二:运行时选择调用哪个函数

举例:

#include <stdio.h>
int add(int a, int b) {
return a + b;
}
int subtract(int a, int b) {
return a - b;
}
int main() {
int (*operation)(int, int);  // 声明一个函数指针
operation = add;             // 指向 add 函数
printf("%d\n", operation(5, 3));
operation = subtract;        // 指向 subtract 函数
printf("%d\n", operation(5, 3));return 0;}

等式关系

int (*p)(int,int) 实际上等价于 int (*)(int,int)  p

说明:

  • 在 C 语言中,声明函数指针的时候,括号的位置可以调整,不影响其含义。这两种声明方式都表达了同样的含义:p是一个指向函数的指针,该函数接受两个整数参数并返回一个整数。

函数指针定义理解一

int *(*Pointer)(int,int);

说明:
这个可以理解为 Pointer 是一个指向函数的指针,而该函数接受两个整数参数并返回一个指向整数的指针

具体解释如下:

  • Pointer:表示这是一个指针。
  • (*Pointer):表示这是一个指向的指针。
  • int *(Pointer):表示这是一个指向返回类型为 int 的指针的指针。
  • int *(Pointer)(int, int):表示这是一个指向接受两个整数参数并返回 int 类型的指针的函数的指针。

所以,如果使用 Pointer 调用函数,该函数应该是这样的:

int* myFunction(int a, int b) {
// some code
return someIntPtr;
}
// 声明一个指向函数的指针
int *(*Pointer)(int, int);
// 使用指针调用函数
int* result = Pointer(3, 5);

上述代码中,Pointer 指向一个函数,该函数接受两个整数参数,并返回一个指向整数的指针。

函数指针定义理解二

typedef int *(*Pointer)(int,int);

这个语句定义了一个函数指针类型,这个类型名字是 Pointer。这个函数指针类型指向一个函数,该函数接受两个整数参数,返回一个指向整数的指针。

具体解释如下:

  • typedef:这是一个关键字,用于定义新的类型别名。
  • int *(*Pointer)(int, int);:这是一个函数指针的声明,表示 Pointer 是一个指向函数的指针,该函数接受两个整数参数并返回一个指向整数的指针。
  • typedef int *(*Pointer)(int, int);:将上述的函数指针声明定义为一个新的类型别名 Pointer。

这样一来,你就可以在代码中使用 Pointer 作为类型名字,而不必每次都写出完整的函数指针声明

typedef int *(*Pointer)(int, int);// 使用 Pointer 定义函数指针变量
Pointer myFunctionPointer;// 使用 Pointer 声明函数
int* myFunction(int a, int b) {// some codereturn someIntPtr;
}// 使用函数指针变量调用函数
int* result = myFunctionPointer(3, 5);

这种方式使得代码更加清晰,特别是当你需要定义多个相同类型的函数指针时。

指针函数

定义

  • 指针函数是一个返回指针的函数,即函数返回的是一个指针。当然,函数本身也可能返回一个函数指针。

用途

  • 指针函数通常用于动态分配内存、返回动态分配的数组等场景。

代码说明:

#include <stdio.h>
#include <stdlib.h>
int* createArray(int size) {
int* arr = (int*)malloc(size * sizeof(int));
return arr;
}
int main() {
int* myArray = createArray(5);
// 使用 myArray
free(myArray);  // 记得释放内存
return 0;
}

指针函数内返回的是函数指针怎么理解

#include <stdio.h>// 定义一个简单的函数,该函数接受两个整数,返回它们的和
int add(int a, int b) {return a + b;
}// 定义一个指针函数,该函数接受一个整数作为参数,返回一个指向函数的指针
int (*getAddFunctionPointer(int value))(int, int) {if (value > 0) {// 如果传入的值是正数,返回指向 add 函数的指针return add;} else {// 如果传入的值是非正数,返回空指针return NULL;}
}int main() {// 调用指针函数,传入正数,得到一个指向 add 函数的指针int (*functionPointer)(int, int) = getAddFunctionPointer(1);if (functionPointer != NULL) {// 使用函数指针调用函数int result = functionPointer(3, 4);printf("Result: %d\n", result);} else {printf("Function pointer is NULL.\n");}return 0;
}

二者区别

定义不同

  • 指针函数本质是一个函数,其返回值为指针。
  • 函数指针本质是一个指针,其指向一个函数。

写法不同

  • 指针函数:int* fun(int x,int y);
  • 函数指针:int (fun)(int x,int y);可以简单粗暴的理解为,指针函数的是属于数据类型的,而函数指针的星号是属于函数名的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/220707.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

跨界电商的科技护航:Socks5代理与代理IP的无限可能

随着全球市场的无缝连接&#xff0c;出海跨界电商成为企业迈向国际舞台的关键一步。然而&#xff0c;面对不同国家和地区的网络环境和限制&#xff0c;科技手段成为企业成功出海的必备利器。本文将深入研究Socks5代理与代理IP在跨界电商中的技术性应用&#xff0c;揭示它们是如…

车载导航系统UI界面,可视化大屏设计(PS源文件)

大屏组件可以让UI设计师的工作更加便捷&#xff0c;使其更高效快速的完成设计任务。现分享车载导航系统科技风蓝黑简约UI界面、车载系统UI主界面、车载系统科技风UI界面、首页车载系统科技感界面界面的大屏Photoshop源文件&#xff0c;开箱即用&#xff01; 若需 更多行业 相关…

1116 多二了一点

若一个正整数有 2n 个数位&#xff0c;后 n 个数位组成的数恰好比前 n 个数位组成的数多 2&#xff0c;则称这个数字“多二了一点”。如 24、6668、233235 等都是多二了一点的数字。 给定任一正整数&#xff0c;请你判断它有没有多二了那么一点。 输入格式&#xff1a; 输入在…

vxe-table循环生成表格,表格里的某些数值设置颜色

业务需求&#xff1a;表格的列名是循环出来的&#xff0c;后台返回每行的表格数据结构如下&#xff0c;需要表格里只有“当期”的行里数值超限waterGuildLine后显示红色。需要在vxe-table里写个插槽&#xff0c;再写个方法。 <vxe-table border ref"dayTableRef" …

hadoop安装包解压之后的操作

Hadoop解压完成之后配置流程 修改hadoop-env.sh和yarn-env.sh 进入hadoop-3.2.4/etc/hadoop/ 修改这两个文件增加 &#xff1a; JAVA_HOME{java的路径}修改配置文件core-site.xml 和 hdfs-site.xml 进入hadoop-3.2.4/etc/hadoop/ 修改这两个文件增加 &#xff1a; // 这是c…

【MySQL】——数据类型及字符集

&#x1f383;个人专栏&#xff1a; &#x1f42c; 算法设计与分析&#xff1a;算法设计与分析_IT闫的博客-CSDN博客 &#x1f433;Java基础&#xff1a;Java基础_IT闫的博客-CSDN博客 &#x1f40b;c语言&#xff1a;c语言_IT闫的博客-CSDN博客 &#x1f41f;MySQL&#xff1a…

js 原型 和 原型链

function Person(name,age){ this.name name this.age age } var p new Person(张三,11) //创建构造函数的时候&#xff0c;解析器会自动为构造函数创建prototype属性&#xff0c;prototype属性对应的对象就是原型对象 // prototype 翻译为 原…

HI3559AV100和FPGA 7K690T的PCIE接口调试记录-续

上文https://blog.csdn.net/fzktongyong/article/details/134963814?spm1001.2014.3001.5501 上一篇文中PCIE实测速度和理论计算有较大偏差&#xff0c;经过尝试后有所提升。 1、提升效果 1&#xff09;、RC写操作&#xff0c;实测速度817MB/s&#xff08;410407&…

SQL进阶 | 外连接

概述 外连接的进阶用法在行列转换中比较有优势&#xff0c;往往存在需要把数据库中的格式转换成报表格式&#xff0c;但是SQL仅仅只是查询数据的语言&#xff0c;格式转换并不是原本的用途。 全外连接 标准 SQL 里定义了外连接的三种类型&#xff0c;如下所示。 左外连接&…

SpringBoot - application.yml 多环境切换解决方案

问题描述 这个问题玩过 SpringCloud 的小伙伴估计会想到用 bootstrap.yml 来解决这个问题。但是如果说为了解决这个问题引入了一堆的 SpringCloud Jar&#xff0c;就感觉杀鸡用牛刀。 于是今天我们想只有 application.yml 自己就可以解决这个问题&#xff0c;如何搞定&#x…

nginx常用命令及配置文件说明

目录 1 前言2 nginx常用命令2.1 查看 Nginx 版本号2.2 启动 Nginx2.3 停止 Nginx2.4 重新加载 Nginx 配置 3 Nginx配置文件说明3.1 **全局块**3.2 **Events 块**3.3 **HTTP 块** 4 结语 1 前言 使用 Nginx 作为 Web 服务器是构建现代网络基础架构的关键一环。在运维和开发领域…

【Socket】Unix环境下搭建简易本地时间获取服务

本文搭建一个Unix环境下的、局域网内的、简易的本地时间获取服务。 主要用于验证&#xff1a; 当TCP连接成功后&#xff0c;可以在两个线程中分别进行读操作、写操作动作当客户端自行终止连接后&#xff0c;服务端会在写操作时收到 SIGPIPE 信号当客户端执行shutdown写操作后&…

kettle+report designer导出带样式的excel包含多个sheet页

场景介绍&#xff1a; 运用pentaho report designer报表设计器&#xff0c;查询数据库字典表生成带有样式的excel&#xff0c;通过kettle pentaho报表输出组件导出形成数据字典&#xff0c;最终形成的数据字典样式如下图&#xff1a; 案例适用范围&#xff1a; pentaho repor…

1. Prism系列之数据绑定

Prism系列之数据绑定 文章目录 Prism系列之数据绑定一、安装Prism二、实现数据绑定三、更换数据源 一、安装Prism 创建一个WPF工程&#xff0c;创建名为 PrismNewSample 的WPF项目。 使用管理解决方案的Nuget包 在上面或许我们有个疑问&#xff1f; 为啥安装prism会跟Pri…

java springboot+jsoup写一段爬虫脚本 将指定地址的 图片链接 文本 超链接地址存入自己的属性类对象中

首先 还是最基本的 要在 pom.xml 引入依赖 <dependency><groupId>org.jsoup</groupId><artifactId>jsoup</artifactId><version>1.14.1</version> </dependency>然后 我们可以在项目中创建一个属性类 我这里就叫 WebContent了…

STM32使用SIM900A、SIM800C、SIM800A完成短信发送、连接onenet上传数据、拨打电话_完整教程

一、前言 本篇文章介绍SIM800C 、SIM800A、SIM900A 等等系列的模块的常用AT指令,讲解模块的使用方法,演示短信发送、拨打电话、网络连接,与服务器通信等常用案例。 如果只是用到发送短信、拨打电话、连接网络通信、这些模块的AT指令是兼容的。 文章最后贴了完整的STM32代码…

isBlank和isEmpty的区别

在Java 11中&#xff0c;​isEmpty()​和 ​isBlank()​方法具有不同的行为和用途。 ​​isEmpty()​方法&#xff1a; ​​isEmpty()​方法是String类已经存在的方法&#xff0c;它用于检查一个字符串是否为空。如果字符串长度为0&#xff0c;则返回true&#xff1b;否则返回…

关于put_response和get_response的总结

Response总结&#xff0c;共三种情况 &#xff08;1&#xff09;每一笔都等response -> 直接get_response 注意put_response的前提是当前的seq的body没有直接结束&#xff0c;这个body一定是最底层发req的那个seq的body &#xff08;2&#xff09;连续发送数据&#xff0…

龙芯loongarch64安装numpy报错“No module named ‘numpy.core._multiarray_umath‘”

前言 在之前编译安装Python3.8的文章中说明了,龙芯仓库的很多包都有问题,安装之后很多无法使用,比如安装numpy后,就会出现“No module named numpy.core._multiarray_umath” 问题复现 配置pip源 vim /etc/pip.conf 复制下面的内容并保存 [global] timeout = 60 index-url…

Java小案例-RocketMQ的11种消息类型,你知道几种?(普通消息和批量消息)

前言 这篇给大家讲普通消息和批量消息&#xff0c;主要配合代码进行讲解&#xff0c;关于RocketMQ的基础知识已经在上篇给大家讲过需要回顾的点击下面这个链接去看 RocketMQ基础知识 普通消息 普通消息其实就很简单&#xff0c;是Apache RocketMQ中最基础的消息形式&#x…