当前位置: 首页 > news >正文

实现深度理解函数指针

对于函数想必大家早已感觉不是很陌生,指针现如今也有着自己独特的了解与认识,但是,对于函数指针不知道屏幕前的您,又能了解多少呢???

对于函数指针,顾名思义,就是指向函数的指针!

1.指向函数的指针变量:

  函数的指针是指函数的入口地址,和数组名代表数组的首地址一样,函数名代表函数的入口地址!若有一个指针变量,存放某一个函数的入口,我们可以通过指向这个函数的指针变量来调用函数!

指向函数的指针变量一般定义为:  类型说明符 ( *  指针变量名 )( )

上述的类型说明符是指:指针变量所指向的函数返回值的类型!列 如:  int ( * p)( );

定义了一个指向函数的指针变量p,它就可以存放一类整型函数的入口地址,主程序中把一个函数的入口地址赋值给它,它就指向哪一个函数!

下面请看代码:

#include <stdio.h>
int add(int x, int y)
{
	return x + y;
}
int main()
{
	int arr[10] = { 0 };
	printf("%p\n", &arr);
	printf("%p\n", arr);

	printf("\n");

	printf("%p\n", add);
	printf("%p\n", &add);


	return 0;
}

上面代码就是将数组名与&数组名,相比较,代码的运行结果为:

大家可以看上面代码的运行结果:答案是显而易见的,对于笔者的专门分开,并将其类比!希望大家可以看出来结果!!

&arr 取出的是整个数组的地址,而 arr是数组名,数组名是数组首元素的地址!!

因此:&add 与  add都是函数的地址,没有什么区别!

对于上述代码进行完善:


#include <stdio.h>
int add(int x, int y)
{
	return x + y;
}
int main()
{
	//int arr[10] = { 0 };
	//int(*p)[10] = &arr;

	int (*pf)(int x, int y) = &add;

	int sum = (*pf)(3, 5);
	printf("sum=%d\n", sum);

	return 0;
}

上述代码中,pf就是函数指针变量!

在定义pf的类型的时候,我们借鉴了上面的int(*p)[10] = &arr; 所以显得简单化了!

对于上述代码的运行结果为:

上述代码的可更改部分为:

          (int ,int )     add
int (*pf)(int x, int y) = &add;

int sum = (*pf)(3, 5);
             pf(3 , 5)
            add(3 , 5)

借鉴上述代码,对于函数指针的定义我们可以用以下的代码概述:

int test(const char* str, double d)
{ }
int main()
{
	int (*pt)(const char*, double) = &test;
	int (*pt)(const char* str, double d) = &test;
}

思考一下:对于下列代码:出自于《C陷阱与缺陷》:如何去思考!

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

上述代码:一句话,可以概述为:

把0直接转化为void(*)()的函数指针,然后去调用0地址出的函数!

 void(*)函数的指针类型

( void(*)())0   :把0当作一个函数的地址

把0 强制类型转化为:void (*)()类型的函数!!

相关文章:

  • C/C++常用预编译指令介绍
  • 杰理强制升级工具4.0使用和原理解析
  • Vue3介绍和安装
  • Linux命令--权限(chmod、chown)--使用/实例
  • flink-sql所有语法详解
  • 【图像分割】基于matlab萤火虫算法图像聚类分割【含Matlab源码 2106期】
  • SQL 入门之第一讲——MySQL 8.0.29安装教程(windows 64位)
  • 用Python进行数学建模(一)
  • 力扣:669. 修剪二叉搜索树,今日份快乐
  • java毕业设计KTV点歌系统mybatis+源码+调试部署+系统+数据库+lw
  • [python] 基于diagrams库绘制系统架构图
  • 2022 年全国职业院校技能大赛(中职组) 网络安全竞赛试题D模块评分标准
  • C++ 语法基础课1 —— 变量、输入输出、顺序语句
  • M的编程备忘录之C++——map和set
  • 《Orange‘s 一个操作系统的实现》第六章
  • 【React系列】如何构建React应用程序
  • 【腾讯Bugly干货分享】从0到1打造直播 App
  • Angular js 常用指令ng-if、ng-class、ng-option、ng-value、ng-click是如何使用的?
  • const let
  • CSS3 聊天气泡框以及 inherit、currentColor 关键字
  • es6--symbol
  • express + mock 让前后台并行开发
  • Puppeteer:浏览器控制器
  • python3 使用 asyncio 代替线程
  • SwizzleMethod 黑魔法
  • 短视频宝贝=慢?阿里巴巴工程师这样秒开短视频
  • 聊聊spring cloud的LoadBalancerAutoConfiguration
  • 浏览器缓存机制分析
  • 每天10道Java面试题,跟我走,offer有!
  • 前嗅ForeSpider教程:创建模板
  • 算法系列——算法入门之递归分而治之思想的实现
  • 通过几道题目学习二叉搜索树
  • 移动互联网+智能运营体系搭建=你家有金矿啊!
  • Mac 上flink的安装与启动
  • (M)unity2D敌人的创建、人物属性设置,遇敌掉血
  • (Redis使用系列) Springboot 使用redis的List数据结构实现简单的排队功能场景 九
  • (Spark3.2.0)Spark SQL 初探: 使用大数据分析2000万KF数据
  • (zz)子曾经曰过:先有司,赦小过,举贤才
  • (博弈 sg入门)kiki's game -- hdu -- 2147
  • (附源码)springboot 房产中介系统 毕业设计 312341
  • (附源码)springboot金融新闻信息服务系统 毕业设计651450
  • (南京观海微电子)——I3C协议介绍
  • (四) Graphivz 颜色选择
  • (转)C#开发微信门户及应用(1)--开始使用微信接口
  • (转)利用ant在Mac 下自动化打包签名Android程序
  • .NET Core 实现 Redis 批量查询指定格式的Key
  • .net redis定时_一场由fork引发的超时,让我们重新探讨了Redis的抖动问题
  • .Net(C#)自定义WinForm控件之小结篇
  • .net访问oracle数据库性能问题
  • .Net通用分页类(存储过程分页版,可以选择页码的显示样式,且有中英选择)
  • /*在DataTable中更新、删除数据*/
  • ??javascript里的变量问题
  • @RequestParam,@RequestBody和@PathVariable 区别
  • @SuppressLint(NewApi)和@TargetApi()的区别
  • [ Linux ] git工具的基本使用(仓库的构建,提交)