函数指针和指针函数的区别

函数指针和指针函数是 C 语言中两个重要的概念,它们在功能和用途上有显著区别。下面将详细解释这两者的含义、用法以及各自的示例。

一、定义

  1. 函数指针(Function Pointer): 函数指针是指向函数的指针。通过函数指针,可以间接调用函数,这在实现回调机制和动态链接时非常有用。

  2. 指针函数(Pointer Function): 指针函数是返回类型为指针的函数。也就是说,该函数会返回一个指针,而这个指针可以指向某种类型的数据。

二、语法

  1. 指针函数的语法

    return_type (*pointer_name)(parameter_types);

    例如,定义一个指向返回 int 类型、接收两个 int 参数的函数指针:

    int (*func_ptr)(int, int);
  2. 指针函数的语法

return_type *function_name(parameter_types);

例如,定义一个返回指向 int 类型的指针的函数:

int* func();

三、示例

1. 函数指针示例

下面的示例展示了如何使用函数指针调用不同的函数,普通定义。

#include <stdio.h>// 定义两个简单的加法和乘法函数
int add(int a, int b) 
{return a + b;
}int multiply(int a, int b) 
{return a * b;
}int main() 
{// 定义一个指向函数的指针int (*operation)(int, int);// 将指针指向加法函数operation = add;printf("Addition: %d\n", operation(5, 3)); // 输出:Addition: 8// 将指针指向乘法函数operation = multiply;printf("Multiplication: %d\n", operation(5, 3)); // 输出:Multiplication: 15return 0;
}

在这个例子中,operation 是一个函数指针,它可以指向不同的函数(addmultiply)。通过函数指针可以动态选择要调用的函数。
​​下面是作为参数传递的示例:

#include <stdio.h>
#include <stdlib.h>// 定义一个比较函数的类型
typedef int (*CompareFunc)(int, int);// 升序比较函数
int compareAscending(int a, int b) 
{return a - b;
}// 降序比较函数
int compareDescending(int a, int b) 
{return b - a;
}// 排序函数,接受一个数组、大小和比较函数作为参数
void sort(int *array, int size, CompareFunc cmp) 
{for (int i = 0; i < size - 1; i++) {for (int j = 0; j < size - i - 1; j++) {if (cmp(array[j], array[j + 1]) > 0) {// 交换int temp = array[j];array[j] = array[j + 1];array[j + 1] = temp;}}}
}// 主函数
int main() 
{int arr[] = {5, 2, 9, 1, 5, 6};int size = sizeof(arr) / sizeof(arr[0]);// 使用升序排序printf("Sorting in ascending order:\n");sort(arr, size, compareAscending);for (int i = 0; i < size; i++) {printf("%d ", arr[i]);}printf("\n");// 重置数组int arr2[] = {5, 2, 9, 1, 5, 6};// 使用降序排序printf("Sorting in descending order:\n");sort(arr2, size, compareDescending);for (int i = 0; i < size; i++) {printf("%d ", arr2[i]);}printf("\n");return 0;
}
2. 指针函数示例

下面展示一个返回指向 int 类型的指针的函数。

#include <stdio.h>
#include <stdlib.h>
// 定义一个函数,返回指向int的指针
int* getArray(int size) 
{// 在堆上分配内存int *array = (int*)malloc(size * sizeof(int));for (int i = 0; i < size; i++) {array[i] = i + 1; // 初始化数组}return array; // 返回数组的指针
}// 主函数
int main() 
{int size = 5;// 获取数组的指针int *myArray = getArray(size);// 打印数组内容for (int i = 0; i < size; i++) {printf("%d ", myArray[i]);}printf("\n");// 释放分配的内存free(myArray);return 0;
}

在上面的代码中,getArray 函数返回一个 int 类型的指针,指向在堆上分配的数组。调用这个函数后,主函数能够使用返回的指针访问数组的元素。

四、应用场景

  1. 函数指针的应用

    • 回调函数:在许多库和框架中,常常通过函数指针实现回调机制。
    • 动态函数调用:在运行时选择不同的函数执行,适用于状态机和事件处理等场景。
  2. 指针函数的应用

    • 动态内存管理:通过返回指针来管理动态分配的内存,特别是在需要返回大量数据时(如数组)。
    • 数据结构的构建:在实现链表、树等数据结构时,常通过指针函数返回指向节点的指针。

五、总结

  • 函数指针 是一种能够指向函数的指针,适用于动态选择函数调用。
  • 指针函数 是一种返回指向某种类型数据的指针的函数,适用于处理动态分配的内存或数据结构。

了解这两者的区别和用法,对于深入理解 C 语言的函数调用机制、内存管理及数据结构设计都具有重要意义。

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

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

相关文章

【网络】HTTP(超文本传输协议)详解

目录 引言一、HTTP的基本概念1.1 什么是HTTP&#xff1f;1.2 HTTP的工作流程1.3 HTTP工作流程图 二、HTTP请求与响应2.1 HTTP请求格式2.2 HTTP响应格式 三、常见的HTTP状态码3.1 其他状态码示例 四、HTTP版本的演变4.1 HTTP/1.04.2 HTTP/1.14.3 HTTP/24.4 HTTP/3 五、HTTP的安全…

卸载 Adobe Genuine Software Client

一、问题描述 使用破jie版Adobe Acrobat Pro DC软件后&#xff0c;会经常弹出以下窗口&#xff1a; 且上述探窗无法直接关掉。即使通过任务管理器将其临时关掉&#xff0c;可等过一段时间后&#xff0c;仍然会再次弹出&#xff0c;严重干扰工作进度。 二、问题解决 &#xff…

点云从入门到精通技术详解100篇-基于结构光测量的三维人脸重建及识别

目录 前言 三维人脸识别技术国内外现状 二维人脸识别研究现状 三维测量技术研究现状 三维人脸识别研究现状 2三维人脸重建及识别系统方案 2.1 基于结构光的三维人脸重建及识别系统构成 2.1.1 典型的投影光栅相位测量几何模型 2.1.1.1 平行式投影系统 2.1.1.2 交叉…

京东云雅典娜刷机步骤(需要拆机)

京东云雅典娜刷机步骤 必须拆机 必须拆机 必须拆机 刷机要用的文件 1.高通驱动文件&#xff08;USB刷机必备&#xff09;&#xff1a;https://pan.quark.cn/s/6405674f981b 2.进入临时uboot的程序&#xff1a;https://pan.quark.cn/s/ebc1d449cb89 3.uboot固件&#xff1a; ht…

电子商城购物平台的设计与开发+ssm(lw+演示+源码+运行)

摘 要 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;电子商城购物平台小程序被用户普遍使用&#xff0c;为方便…

基于 Spring Boot 和 Vue 的门票销售创新系统

作者介绍&#xff1a;✌️大厂全栈码农|毕设实战开发&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导。 &#x1f345;获取源码联系方式请查看文末&#x1f345; 推荐订阅精彩专栏 &#x1f447;&#x1f3fb; 避免错过下次更新 Springboot项目精选实战案例 更多项目…

【Python】Python自习课:第一个python程序

【Python】Python自习课&#xff1a;第一个python程序 示例

docker-compose安装rabbitmq 并开启延迟队列和管理面板插件(rabbitmq_delayed_message_exchange)

问题&#xff1a; 解决rabbitmq-plugins enable rabbitmq_delayed_message_exchange &#xff1a;plugins_not_found 我是在docker-compose环境部署的 services:rabbitmq:image: rabbitmq:4.0-managementrestart: alwayscontainer_name: rabbitmqports:- 5672:5672- 15672:156…

103 - Lecture 2 Table and Data Part 1

SQL - Tables and Data Part 1 Relational Database Management System(RDBMS) 关系型数据库管理系统&#xff08;RDBMS&#xff09;是基于关系模型的数据库系统&#xff0c;它支持多种关系操作。关系模型是一种数据存储和检索的模型&#xff0c;它使用表格来组织数据&#x…

Linux云计算个人学习总结(二)

高级文件系统 一、RSYNC概述 1、作用&#xff1a;快速的文件复制工具&#xff08;支持本地和远程&#xff09;&#xff0c;以及删除、查看等基本功能。 2、特点&#xff1a;支持实时&#xff08;inotify、sersync&#xff09;的增量备份工具3、模式&#xff1a;检查模式&#…

PropTypes 和 TypeScript 在 React 中的比较

文章目录 引言PropTypes什么是 PropTypes&#xff1f;如何使用 PropTypes优点缺点 TypeScript什么是 TypeScript&#xff1f;如何使用 TypeScript优点缺点 选择建议总结 引言 在 React 开发中&#xff0c;组件的可复用性和可维护性至关重要。为了确保组件接收到正确的 props&a…

CommunityToolkit.Mvvm如何使用

CommunityToolkit.Mvvm 是一个现代、快速和模块化的 MVVM 库&#xff0c;用于 .NET 应用程序。以下是如何使用 CommunityToolkit.Mvvm 的基本步骤&#xff1a; 安装包&#xff1a; 你可以通过 NuGet 包管理器安装 CommunityToolkit.Mvvm。在 Visual Studio 中&#xff0c;你可以…

【自动化利器】12个评估大语言模型(LLM)质量的自动化框架

LLM评估是指在人工智能系统中评估和改进语言和语言模型的过程。在人工智能领域&#xff0c;特别是在自然语言处理&#xff08;NLP&#xff09;及相关领域&#xff0c;LLM评估具有至高无上的地位。通过评估语言生成和理解模型&#xff0c;LLM评估有助于细化人工智能驱动的语言相…

mybatis源码解析-sql执行流程

1 执行器的创建 1. SimpleExecutor 描述&#xff1a;最基本的执行器&#xff0c;每次查询都会创建新的语句对象&#xff0c;并且不会缓存任何结果。 特点&#xff1a; 每次查询都会创建新的 PreparedStatement 对象。 不支持一级缓存。 适用于简单的查询操作&#xff0c;不…

儿童安全座椅行业全面深入分析

儿童安全座椅就是一种专为不同体重&#xff08;或年龄段&#xff09;的儿童设计&#xff0c;将孩子束缚在安全座椅内&#xff0c;能有效提高儿童乘车安全的座椅。欧洲强制性执行标准ECE R44/03的定义是&#xff1a;能够固定到机动车辆上&#xff0c;带有ISOFIX接口、LATCH接口的…

【React 的理解】

谈一谈你对 React 的理解 对待这类概念题&#xff0c;讲究一个四字口诀“概用思优”&#xff0c;即“讲概念&#xff0c;说用途&#xff0c;理思路&#xff0c;优缺点&#xff0c;列一遍” 。 React 是一个网页 UI 框架&#xff0c;通过组件化的方式解决视图层开发复用的问题&a…

对象的接口与设计模式在其中的作用

对象的接口 对象的接口定义了对象的行为和如何与外界进行交互。以下是对象接口的详细解释&#xff1a; 成员函数&#xff08;Member Functions&#xff09; 定义&#xff1a;成员函数是定义在类中的函数&#xff0c;用于实现类的行为。成员函数可以通过对象来调用&#xff0…

Pytest-Bdd-Playwright 系列教程(6):在测试步骤函数中设置别名数据共享

Pytest-Bdd-Playwright 系列教程&#xff08;6&#xff09;&#xff1a;在测试步骤函数中设置别名&数据共享 前言一、步骤别名二、特性文件三、测试脚本四、运行测试五、小测验总结 前言 有的时候&#xff0c;为了提高可读性&#xff0c;我们需要使用不同的名称来声明相同的…

【笔记】变压器-热损耗-频响曲线推导 - 03 变压器参数-特性

参考《Mn-Zn开关电源用铁氧体磁心 PQ系列》&#xff0c;March 2014版 1.可能选择的型号和参数 PQ系列的这种铁氧体结构设计是TDK首创的。 优势是&#xff0c;相对E, EER磁芯&#xff0c;安装面积更小材质选择 PC47PC90PC95尺寸 PQ20/16 最小PQ50/50 最大 2.特性 2.1 温升与…

Unity性能优化 -- 性能分析工具

Stats窗口Profiler窗口Memory Profiler其他性能分析工具&#xff08;Physica Debugger 窗口&#xff0c;Import Activity 窗口&#xff0c;Code Coverage 窗口&#xff0c;Profile Analyzer 窗口&#xff0c;IMGUI Debugger 窗口&#xff09; Stats 统级数据窗口 game窗口 可…