C语言——深入理解指针——函数指针

一、函数指针变量

1.1 函数指针变量的创建

什么是函数指针变量呢?

函数指针变量应该是用来存放函数地址的,未来通过地址能够调⽤函数的。 那么函数是否有地址呢?

我们做个测试:

#include <stdio.h>
void test()
{printf("hehe\n");
}
int main()
{printf("test: %p\n", test);printf("&test: %p\n", &test);return 0;
}

结果如下:

 

确实打印出来了地址,所以函数是有地址的,函数名就是函数的地址,当然也可以通过&函数名的方式获得函数的地址

如果我们要将函数的地址存放起来,就得创建函数指针变量咯,函数指针变量的写法其实和数组指针非常类似。如下:

void test()
{printf("hehe\n");
}
void (*pf1)() = &test;
void (*pf2)() = test;
int Add(int x, int y)
{return x + y;
}
int(*pf3)(int, int) = Add;
int(*pf3)(int x, int y) = &Add;//x和y写上或者省略都是可以的

函数指针类型解析:

int (*pf3) (int x, int y)
| | ------------
| | |
| | pf3指向函数的参数类型和个数的交代
| 函数指针变量名
pf3指向函数的返回类型
int (*) (int x, int y) //pf3函数指针变量的类型

1.2 函数指针变量的使用

通过函数指针调用指针指向的函数。

#include <stdio.h>
int Add(int x, int y)
{return x + y;
}
int main()
{int(*pf3)(int, int) = Add;printf("%d\n", (*pf3)(2, 3));printf("%d\n", pf3(3, 5));return 0;
}

输出结果:

 

我们这里可以看出,针对与函数指针变量,对于对函数指针变量进行解引用操作和不进行解引用操作都可以调用Add函数并使用,所以对于函数指针变量的使用解引用操作符可以不写。

1.3 typedef关键字

typedef 是用来类型重命名的,可以将复杂的类型,简单化。

比如,你觉得 unsigned int 写起来不方便,如果能写成 uint 就⽅便多了,那么我们可以使用:

typedef unsigned int uint;
//将unsigned int 重命名为uint

如果是指针类型,能否重命名呢?其实也是可以的,比如,将 int* 重命名为 ptr_t ,这样写: 

typedef int* ptr_t;

但是对于数组指针和函数指针稍微有点区别: ⽐如我们有数组指针类型 int(*)[5] ,需要重命名为 parr_t ,那可以这样写: 

typedef int(*parr_t)[5]; //新的类型名必须在*的右边

函数指针类型的重命名也是⼀样的,⽐如,将 void(*)(int) 类型重命名为 pf_t ,就可以这样写:

typedef void(*pfun_t)(int);//新的类型名必须在*的右边
void (*signal(int , void(*)(int)))(int);
//简化后
typedef void(*pfun_t)(int);
pfun_t signal(int, pfun_t);

二、函数指针数组 

数组是⼀个存放相同类型数据的存储空间,我们已经学习了指针数组,

比如:

int *arr[10];
//数组的每个元素是int*

那要把函数的地址存到⼀个数组中,那这个数组就叫函数指针数组,那函数指针的数组如何定义呢? 

int (*parr1[3])();
int *parr2[3]();
int (*)() parr3[3];

答案是:parr1

parr1 先和 [ ] 结合,说明 parr1是数组,数组的内容是什么呢?

是 int (*)() 类型的函数指针。 

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

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

相关文章

软考中级哪个科目最简单?

那必须是系统集成项目管理工程师&#xff01; 系统集成项目管理工程师考试内容少&#xff0c;题型简&#xff0c;报考门槛低&#xff0c;零基础就能报考&#xff0c;学习内容比较简单&#xff0c;接近工作和生活。 系统集成项目管理工程师证书是中国计算机技术职业资格&#…

代码随想录算法训练营第23期day60|84.柱状图中最大的矩形

一、84.柱状图中最大的矩形 力扣题目链接 42接雨水 是找每个柱子左右两边第一个大于该柱子高度的柱子&#xff0c;而本题是找每个柱子左右两边第一个小于该柱子的柱子。 本题是要找每个柱子左右两边第一个小于该柱子的柱子&#xff0c;所以从栈头&#xff08;元素从栈头弹出…

2024年湖北省水利厅的安管人员水安ABC证报考指南

2024年湖北省水利厅的安管人员水安ABC证报考指南 关于水安ABC报考&#xff0c;很多企业乃至个人都不是很清楚流程&#xff0c;叙后尘来给大家科普一下报考详细细节。2023年年度仅剩一次的报考时间定于2023年11月23日至11月28日。在这个时间段才可以网上填写报考资料&#xff0…

js读取json文件

1. 原生的两种方法 1.1 XMLHttpRequest const xhr new XMLHttpRequest(); xhr.overrideMimeType("application/json"); xhr.open(GET, data.json, true); xhr.onreadystatechange function () {if (xhr.readyState 4 && xhr.status 200) {const data …

使用EasyPlayer播放H.265视频流

使用EasyPlayer播放H.265视频流 EasyPlayer流媒体视频播放器 EasyPlayer流媒体视频播放器 EasyPlayer流媒体视频播放器可支持H.264与H.265编码格式&#xff0c;性能稳定、播放流畅&#xff0c;能支持RTSP、RTMP、HLS、FLV、WebRTC等格式的视频流播放&#xff0c;并且已实现网页…

【交易计划】MT4外汇交易新手如何制定有效的交易计划?

外汇交易作为一种高风险高回报的投资方式&#xff0c;对于新手而言&#xff0c;制定一个有效的交易计划至关重要。良好的交易计划可以帮助他们更好地分析市场、管理风险&#xff0c;并制定适合自己的入场和出场策略。本文将详细介绍MT4外汇交易新手如何制定有效的交易计划&…

Cannot read properties of undefined (reading ‘resetFields‘)“ 报错解决

遇到这种报错 先去相关页面搜索关键字 定位到具体的报错代码 Cannot read properties of undefined (reading ‘resetFields’)" 关键字&#xff1a;resetFields 此方法作用&#xff1a;对整个表单进行重置 将所有字段值重置为初始值并移除校验结果 报错场景&#xff1a;…

坚鹏:湖北银行数字化转型背景下银行运营管理创新培训圆满结束

湖北银行正式成立于2011年2月27日&#xff0c;总部设在武汉。现有员工5000余人。营业网点从成立之初的93家增长至241家&#xff0c;实现全省17个市州、59个县域营业网点全覆盖。截至2022年末&#xff0c;全行资产总额4026亿元&#xff0c;存款总额2956亿元&#xff0c;贷款总额…

人工标签不准确的一种解决方案:PCA降维可视化筛选正样本

背景 在实际的业务场景里&#xff0c;用会话文本构建模型&#xff08;机器学习/深度学习&#xff09;来做意图分类之类的任务时&#xff0c;经常会出现人工打标不够准确的问题&#xff0c;标签都不准确的话模型当然无法学习到有效信息了。这个问题真的非常头疼…除了与业务沟通…

d3dcompiler_47.dll缺失怎么修复,d3dcompiler_47.dll的作用有哪些

d3dcompiler_47.dll丢失是一种常见的电脑问题。如果你遇到了这个问题&#xff0c;不要惊慌&#xff0c;下面的方法可以帮助你解决。本文将详细介绍解决d3dcompiler_47.dll丢失问题的步骤&#xff0c;让你手把手地学会。 一.解决d3dcompiler_47.dll丢失问题的步骤 解决方法一&a…

CSS伪类选择器详细讲解

前言 伪类选择器在CSS中起到的作用可以说是至关重要的&#xff0c;如果CSS没有伪类选择器&#xff0c;有很多效果都要借助js来完成&#xff0c;这样不仅代码量增加&#xff0c;维护起来你难度也大。这样程序员的工作量大&#xff0c;也违背了CSS诞生的作用&#xff0c;就是提高…

洛谷 P1250 种树

种树 题目背景 一条街的一边有几座房子&#xff0c;因为环保原因居民想要在路边种些树。 题目描述 路边的地区被分割成块&#xff0c;并被编号成 1 , 2 , … , n 1, 2, \ldots,n 1,2,…,n。每个部分为一个单位尺寸大小并最多可种一棵树。 每个居民都想在门前种些树&#…

重磅!TikTok Shop将以新方式重启印尼业务

据报道&#xff0c;TikTok将通过与印尼电商平台合作的方式重启电商业务。 据悉&#xff0c;印尼合作社和中小企业部就TikTok Shop将在印尼重新开业的消息发表了讲话。合作社和中小企业部Temmy Satya Permana证实TikTok Shop将在印尼重新开业的消息。他表示&#xff0c;TikTok …

使用 Python脚本在3DMAX中加载图像和读取图像中的像素值

如何使用Python在3dmax中加载和显示图像文件&#xff1f;我们先看下面的代码&#xff1a; *测试的3dmax文件和图像文件位于同一目录中。 from MaxPlus import BitmapManagerimage_file_path rje_gray_02_4k.exrbmp_storage MaxPlus.Factory.CreateStorage(17)bmp_info bmp…

探索数字孪生的潜力:五个最有前景的行业

数字孪生技术正在引领一场新的工业革命&#xff0c;其潜力正在被全球范围内的行业所认识和利用。在未来&#xff0c;数字孪生技术将在许多行业中发挥重要作用&#xff0c;本文带大家共同解析未来数字孪生技术五个最有发展前景的行业。 1.制造业 数字孪生技术可以帮助制造商模…

Leetcode——169 多数元素

我的答案 class Solution {public int majorityElement(int[] nums) {int len nums.length;Arrays.sort(nums);int count 1;int res 0;if(len 1){return nums[0];}for(int i0; i<len-1; i){if(nums[i]nums[i1]){count;}else{count 1;}if(count>len/2){res nums[i]…

springboot post添加URL添加参数

出现 MissingServletRequestParameterException: Required String parameter pageNumber is not present 异常的原因是在请求中没有提供名为 pageNumber 的参数。 请确保发送 POST 请求时&#xff0c;在请求的 URL 或请求体中提供了名为 pageNumber 的参数&#xff0c;以满足方…

【问题定位】通过看Mybatis源码解决系统问题

开发需求好好的&#xff0c;运维同事突然发现了一个问题&#xff0c;某个任务的详情页面加载不出来。看日志&#xff0c;系统在进行查询操作的时候抛出空指针异常。感觉是Mybatis内部异常&#xff0c;所以就跟踪源码看下Mybatis运行到哪一步报错的。 DefaultSqlSession#select…

MySQL大表设计

存储大规模数据集需要仔细设计数据库模式和索引&#xff0c;以便能够高效地支持各种查询操作。在面对数亿条数据&#xff0c;每条数据包含数百个字段的情况下&#xff0c;以下是我能想到的在设计数据库的时候需要注意的内容&#xff0c;不足之处欢迎各位在评论区批评指正&#…

2023年亚太杯数学建模思路 - 案例:粒子群算法

文章目录 1 什么是粒子群算法&#xff1f;2 举个例子3 还是一个例子算法流程算法实现建模资料 # 0 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 1 什么是粒子群算法&#xff1f; 粒子群算法&#xff08;Pa…