函数指针详解和简单使用

news2024/11/24 17:29:02

概念

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

引入 

#include <stdio.h>

void test()
{
    printf("hehe\n");
}
int main()
{
    printf("%p\n", test);
    printf("%p\n", &test);
//函数名是等于函数地址,所以两个打印函数结果一样
    return 0;
}

这个代码输出的结果是一样的,输出的是两个地址。因为,函数名是等于函数地址。

那我们的函数的地址要想保存起来,怎么保存?直接调用下面这句:

void  (*pfun)(void) = test;
(*pfun)();  //test(); 或者 pfun();

pfun1先和*结合,说明pfun1是指针,指针指向的是一个函数,指向的函数无参数,返回值类型为void

上面这个是无参例子,下面讲有参例子 :

#include <stdio.h>
#include <string.h>

int test(const char* str)
{
	printf("test()\n");
	return 0;
}

int main()
{
	//函数指针 - 也是一种指针,是指向函数的指针
	printf("%p\n", test);
	printf("%p\n", &test);

    //函数名是等于函数地址,所以两个打印函数结果一样

	int (* pf)(const char*) = test;
	(*pf)("abc");
	//pf 和 test 等价,则(*pf)("abc"); 可以写成 test("abc"); 或者 pf("abc");
	
	return 0;
}

//这里abc是参数,可以随便给,只要是字符型就可以。因为这里没有具体参数调用

 通过上面两个简单案例,我们可以总结函数指针的使用模板,如下:

int Add(int x)
{
	return 0;
}

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

 其他陷阱

 注 :来源《C陷阱和缺陷》

(*(void (*)())0)();  //代码1

void (* signal(int,void( * )( int ) ) )(int); //代码2

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

在代码1里面,数字0前面的部分:void(*)()怎么理解?如果我们写成void(*p)()呢?

可以这么理解:

  1. void:这是函数指针 p 所指向的函数的返回类型。在这里,void 表示该函数没有返回值。

  2. (*p):这部分声明了一个指针变量 p,它可以指向一个函数。* 是指针声明的一部分,表示 p 是一个指针。

  3. ():这一对括号表示指针 p 所指向的函数不接受任何参数。如果要指向接受参数的函数,括号内会包含参数列表。

 综合起来,void(*p)() 表示一个指向不接受任何参数并且没有返回值的函数的指针。你可以将这个指针指向相应类型的函数,然后通过该指针调用该函数。

void(*)()理解:void()() 表示函数指针类型,类似于int*  char*这些类型一样

下一步理解:( void()() )0

  1. (void()()):这是一个类型转换表达式,试图将一个整数值 0 转换为一个函数指针类型。但是,(void()()) 不是有效的类型转换,因为它没有指定要将整数值转换为哪种函数类型。如(int)3.14

  2. 0:这是一个整数字面值,表示零。

 总结:这里是一次函数调用,调用的是0作为地址处的函数。调用0地址处的这个函数。

 再理解 :* ( void()() )0

 *:这是一个解引用运算符。它用于访问指针所指向的对象或函数

  1. (void()())0 尝试将整数 0 转换为一个函数指针类型,但由于没有明确的函数指针类型,这通常会导致编译错误。

  2. * 解引用运算符试图访问一个函数指针,但由于前面的转换通常是非法的,这也会导致编译错误。

所以代码1,可以这样理解:

(void(*)()) 表示一个函数指针类型,该指针指向一个不接受任何参数且没有返回值(void)的函数。然后,( *(void(*)())0 ) 尝试将整数常量 0 转换为这种函数指针类型,但通常这是不合法的,因为整数不能直接转换为函数指针类型。

接着,( *(void(*)())0 )( ) 看起来像一个函数调用表达式,它试图通过解引用一个无效的函数指针来调用一个函数。这也是不合法的,因为在这种情况下,函数指针是无效的(尝试将整数转换为函数指针是不合法的操作)。

 代码1归纳

 

 void (* signal(int,void( * )( int ) ) )(int);

这是一个 C 语言中的函数声明,表示 `signal` 是一个函数,它接受两个参数并返回一个函数指针。让我逐步解释它的各个部分:

1. `signal`:这是函数的名称,表示函数的标识符是 `signal`。

2. `int`:这是函数 `signal` 的第一个参数,它是一个整数类型。

3. `void(*)(int)`:这是函数 `signal` 的第二个参数,它是一个指向函数的指针类型。具体来说,它是一个指向接受一个整数参数并且没有返回值的函数的指针类型。

4. `(* signal(int, void(*)(int)))`:这部分表示函数 `signal` 接受两个参数,一个整数和一个函数指针,然后返回一个函数指针。

5. `void(*)(int)`:最后,这部分表示 `signal` 函数返回的函数指针的类型,它是一个指向接受一个整数参数并且没有返回值的函数的指针类型。

综合起来,这个函数声明的含义是:`signal` 是一个函数,它接受一个整数参数和一个指向接受整数参数并且没有返回值的函数的指针参数,然后返回一个指向类似函数的指针,这个函数指针接受一个整数参数并且没有返回值。

这种类型的函数通常用于设置信号处理程序,其中第一个参数是信号的编号,第二个参数是一个函数指针,指向在接收到特定信号时要执行的处理程序。函数 `signal` 返回的函数指针通常用于保存先前的信号处理程序的引用,以便以后可以还原它。

 代码2归纳

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

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

相关文章

基于 SpringBoot+Vue 的大学生租房网站

1 简介 本大学生租房系统使用简洁的框架结构&#xff0c;专门用于用户浏览首页&#xff0c;房屋信息&#xff0c;房屋评价&#xff0c;公告资讯&#xff0c;个人中心&#xff0c;后台管理&#xff0c;意见反馈等信息&#xff0c;对个人信息进行修改等&#xff0c;以及系统管理…

基于Java的大学生就业招聘系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作…

Java基础---第十篇

系列文章目录 文章目录 系列文章目录一、说说Java 中 IO 流二、 Java IO与 NIO的区别(补充)三、java反射的作用于原理一、说说Java 中 IO 流 Java 中 IO 流分为几种? 按照流的流向分,可以分为输入流和输出流; 按照操作单元划分,可以划分为字节流和字符流; 按照流的角色…

【笔试强训day02】倒置字符串 排序子序列

​&#x1f47b;内容专栏&#xff1a; 笔试强训集锦 &#x1f428;本文概括&#xff1a;C笔试强训day02。 &#x1f43c;本文作者&#xff1a; 阿四啊 &#x1f438;发布时间&#xff1a;2023.10.1 二、day02 1.倒置字符串 题目描述&#xff1a; 将一句话的单词进行倒置&…

工厂模式和单例模式

目录 一.设计模式 二.工厂模式和单例模式 &#x1f41e;单例模式 1.饿汉模式 2.懒汉模式 &#xff08;1&#xff09;问题一&#xff1a;大量对象的创建 &#xff08;2&#xff09;问题二&#xff1a;加锁导致阻塞等待 &#xff08;3&#xff09;问题三&#xff1a;指令…

MySql进阶篇---006:存储引擎,索引,SQL优化,视图、存储过程、变量、流程控制、游标、存储函数、触发器

1. 存储引擎 1.1 MySQL体系结构 1).连接层 最上层是一些客户端和链接服务&#xff0c;包含本地sock 通信和大多数基于客户端/服务端工具实现的类似于TCP/IP的通信。主要完成一些类似于连接处理、授权认证、及相关的安全方案。在该层上引入了线程池的概念&#xff0c;为通过认证…

【面试经典150 | 矩阵】螺旋矩阵

文章目录 写在前面Tag题目来源题目解读解题思路方法一&#xff1a;模拟方法二&#xff1a;按层模拟 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法&#xff0c;两到三天更新一篇文章&#xff0c;欢迎催更…… 专栏内容以分析题目为主&#xff0c;并附带一些对于…

04. Springboot集成Mybatis-flex(二)

1、前言 上一篇文章《Springboot集成Mybatis-flex&#xff08;一&#xff09;》提到Mybatis Flex和Spring Boot的初步集成和基础使用。今天我们再来探索Mybatis Flex其他特性的使用。 2、数据填充 数据填充指的是&#xff0c;当 Entity 数据被插入 或者 更新的时候&#xff…

Ghostscript 字体处理深究: 解决字体缺失问题

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

Hello World!1分钟配置好你的Go环境

目录 一、简介为什么选择Golang&#xff1f;Golang与其他语言的对比核心特性应用场景社区和生态系统性能标准企业级应用 二、环境要求操作系统WindowsLinux/UnixmacOS 硬件需求其他依赖软件异常情况和处理方法 三、下载和安装GolangWindows系统使用官方安装包使用Chocolatey&am…

使用CreateProcess崩溃:处未处理的异常: 0xC0000005: 写入位置 0x00415652 时发生访问冲突

问题代码 if (!CreateProcess(NULL,L"pela.exe",NULL,NULL,TRUE,NULL,NULL,NULL,&si,&pi)){return 0;}如果CreateProcess的第二个参数字符串是常量或者是储存在堆中的就会被写保护&#xff0c;崩溃。如果字符串定义到栈或者全局变量就不存在此问题了。 正确的…

初级篇—第二章SELECT查询语句

文章目录 什么是SQLSQL 分类SQL语言的规则与规范阿里巴巴MySQL命名规范数据导入指令 显示表结构 DESC基本的SELECT语句SELECTSELECT ... FROM列的别名 AS去除重复行 DISTINCT空值参与运算着重号查询常数过滤数据 WHERE练习 运算符算术运算符加减符号乘除符号取模符号 符号比较运…

SNERT预备队招新CTF体验赛-Misc(SWCTF)

目录 1、最简单的隐写 2、旋转我 3、is_here 4、zip伪加密 5、压缩包密码爆破 6、我就藏在照片里 7、所以我放弃了bk 8、套娃 9、来自银河的信号 10、Track_Me 11、勇师傅的奇思妙想 1、最简单的隐写 下载附件后&#xff0c;图片格式并不支持打开 根据题目提示&…

Window 安装多个版本的 java 并按需切换

1、按需下载对应版本的 java 官网链接&#xff1a;Java Downloads | Oracle 2、执行安装程序&#xff0c;根据安装向导一步一步走就行&#xff0c;每个版本安装在不同的目录下。 3、配置环境变量 a&#xff09;为每个版本 java 新建不同名称的 JAVA_HOME 系统变量&#xff0…

最优化:建模、算法与理论(最优性理论

第五章 最优性理论 在实际中最优化问题的形式多种多样&#xff0c;给定一类具体的优化问题&#xff0c;我们首先需要分析其解的存在性。如果优化问题的解存在&#xff0c;再考虑如何设计算法求出最优解&#xff0c;一般的非凸优化问题可能存在很多局部极小解&#xff0c;但其往…

使用WPS自动化转换办公文档: 将Word, PowerPoint和Excel文件转换为PDF

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

IDEA-2023-jdk8 HelloWorld的实现

目录 1 新建Project - Class 2 编写代码 3 运行 1 新建Project - Class 选择"New Project"&#xff1a; 指名工程名、使用的JDK版本等信息。如下所示&#xff1a; 接着创建Java类&#xff1a; 2 编写代码 public class HelloWorld {public static void main(S…

桂院校园导航 | 云上高校导航 云开发项目 二次开发教程 1.2

Gitee代码仓库&#xff1a;桂院校园导航小程序 GitHub代码仓库&#xff1a;GLU-Campus-Guide 演示视频 【2023广西赛区 | 三等奖】中国大学生计算机设计大赛 云上高校导航 先 假装 大伙都成功安装了云开发项目&#xff0c;并能在 微信开发者工具 和 手机 上正确运行。 接着就…

【生物信息学】使用HSIC LASSO方法进行特征选择

目录 一、实验介绍 二、实验环境 1. 配置虚拟环境 2. 库版本介绍 3. IDE 三、实验内容 0. 导入必要的工具 1. 读取数据 2. 划分训练集和测试集 3. 进行HSIC LASSO特征选择 4. 特征提取 5. 使用随机森林进行分类&#xff08;使用所有特征&#xff09; 6. 使用随机森…

【面试经典150 | 矩阵】有效的数独

文章目录 写在前面Tag题目来源题目解读解题思路方法一&#xff1a;一次遍历数组 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法&#xff0c;两到三天更新一篇文章&#xff0c;欢迎催更…… 专栏内容以分析题目为主&#xff0c;并附带一些对于本题涉及到的数据结…