C语言 函数指针详解

一、函数指针

1.1、概念

函数指针:首先它是一个指针,一个指向函数的指针,在内存空间中存放的是函数的地址

示例:

int Add(int x,int y)
{return x+y;}
int main()
{printf("%p\n",&Add);//打印一下函数Add()的地址printf("%p\n",Add);//数组名等于数组首元素地址,那函数名是等于函数地址吗?return 0;
}

函数名是等于函数地址的!

1.2、函数指针的使用方法

函数指针的定义函数的返回值类型(*指针名)(函数的参数列表类型

int Add(int x, int y)
{return x+y;
}int main()
{int (*pf)(int, int) = &Add;//函数指针定义,返回值类型和参数类型与函数Add()相同
}

1.3、怎么使用函数指针去调用函数呢?

void Add(int x, int y){return x+y;}int main(){int (*pf)(int,int)=&Add;int ret=(*pf)(3,5);
}

解析:
        int ret=(*pf)(3,5),此时就相当于通过函数名调用: int ret=Add(3,5);},我们又知道:函数名是等于&函数名的,所以int (*pf)(int,int)=&Add,可改成:int (*pf)(int,int)=Add;此时Add等价于pf,所以:int ret=(*pf)(3,5);语句可改成:int ret=pf(3,5);等价于int ret=Add(3,5),故我们知道了对于:int ret=(*pf)(3,5);语句来说,*是没有意义的,有一个或多个或者没有都不影响;
 

二、阅读两段有趣的代码

注:来源于《c陷阱和缺陷》;

1.( *(void( *)( ))0 )( )
解析:
这段代码的含义是:

(1)调用0地址处的函数
(2)该函数无参数,返回值是void
(3)拆分:
·     ·●void()() 表示函数指针类型
     ··●( void()() )0 表示对0进行强制类型转换,把0强制类型转换成一个函数的地址;如(int)3.14
··     ●* ( void()() )0 表示对0地址处的函数进行了解引用操作
      ··●( ( void(*)() )0)() 则表示调用0地址处的函数
(4)请看图解:
在这里插入图片描述

 

2.void (* signal(int,void( * )( int ) ) )(int)
解析:

(1)signal和()先结合,说明signal是一个函数名
(2)signal函数第一个参数的类型为int,第二个参数的类型为函数指针,该函数指针指向一个参数为int,返回值为void的函数;
(3)signal 函数的返回类型也是一个函数指针,该函数指针,指向一个参数为int,返回值为void函数
(4)请看图解:
在这里插入图片描述

综上,signal是一个函数声明;
 


 

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

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

相关文章

List集合的对象传输的两种方式

说明:在一些特定的情况,我们需要把对象中的List集合属性存入到数据库中,之后把该字段取出来转为List集合的对象使用(如下图) 自定义对象 public class User implements Serializable {/*** ID*/private Integer id;/*…

AWS Amplify 部署node版本18报错修复

Amplify env:Amazon Linux:2 Build Error : Specified Node 18 but GLIBC_2.27 or GLIBC_2.28 not found on build 一、原因 报错原因是因为默认情况下,AWS Amplify 使用 Amazon Linux:2 作为其构建镜像,并自带 GLIBC 2.26。不过,…

【无标题】一篇文章带你彻底理解Java ArrayList数据结构详解

一篇文章带你彻底理解Java ArrayList数据结构详解 基本概念: ​ **之前创建数组的时候,需要声明提前声明数组的大小,**ArrayList是一个可以动态修改的数组,与普通数组的区别就是没有固定大小的限制,它会动态调整长度…

数据结构初阶--二叉树的顺序结构之堆

目录 一.堆的概念及结构 1.1.堆的概念 1.2.堆的存储结构 二.堆的功能实现 2.1.堆的定义 2.2.堆的初始化 2.3.堆的销毁 2.4.堆的打印 2.5.堆的插入 向上调整算法 堆的插入 2.6.堆的删除 向下调整算法 堆的删除 2.7.堆的取堆顶元素 2.8.堆的判空 2.9.堆的求堆的…

飞桨AI Studio可以玩多模态了?MiniGPT4实战演练!

MiniGPT4是基于GPT3的改进版本,它的参数量比GPT3少了一个数量级,但是在多项自然语言处理任务上的表现却不逊于GPT3。项目作者以MiniGPT4-7B作为实战演练项目。 创作者:衍哲 体验链接: https://aistudio.baidu.com/aistudio/proj…

一语道破 python 迭代器和生成器

简而言之:迭代器是一个抽象化的概念,在python中表示访问数据集合中元素的一种方式;生成器也是一个抽象化的概念,在python 中,边循环边生成所需数据,是一种时间换空间的方法。从访问数据方式上来看&#xff…

[数据集][目标检测]遛狗不牵绳数据集VOC格式-1980张

数据集格式:Pascal VOC格式(不包含分割路径的txt文件和yolo格式的txt文件,仅仅包含jpg图片和对应的xml) 图片数量(jpg文件个数):1980 标注数量(xml文件个数):1980 标注类别数:5 标注类别名称:["dog","p…

Qt编写自定义控件:自定义表头实现左右两端上部分圆角

如上图,左上角和右上角凸出来了。设置表格圆角和表头圆角和QHeaderView::section圆角都不管用。解决此问题需要重写QHeaderView的paintSection()函数: class CustomHeaderView : public QHeaderView { public:explicit CustomHeaderView(Qt::Orientati…

NsPack3.x脱壳手记

发现是NsPack3.x的壳 使用ESP守恒快速脱壳 F9遇到popfd后下面的jmp就是通往OEP了 打开LordPE准备转储映像, 首先调整下ImageSize, 接着dump full 接着不要退出目前的调试, 打开Scylla修复IAT, 把OEP的VA地址输入到OEP处, 接着按照如下图所示步骤 完成后如下, 但NsPack3.x…

shell命令

#!/bin/bash read -p "请输入一个文件名:" fileName posexpr index $fileName \. typeexpr substr $fileName $((pos1)) 2if [ $type sh ] thenif [ -x $fileName ]thenbash $fileNameelsechmod ax $fileNamefi firead -p "请输入第一个文件名&…

【LeetCode】226.翻转二叉树

题目 给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。 示例 1: 输入:root [4,2,7,1,3,6,9] 输出:[4,7,2,9,6,3,1]示例 2: 输入:root [2,1,3] 输出:[2,3,1]示例 3…

opencv 30 -图像平滑处理01-均值滤波 cv2.blur()

什么是图像平滑处理? 图像平滑处理(Image Smoothing)是一种图像处理技术,旨在减少图像中的噪声、去除细节并平滑图像的过渡部分。这种处理常用于预处理图像,以便在后续图像处理任务中获得更好的结果。 常用的图像平滑处理方法包括…