当前位置:网站首页>函数名指针和函数指针
函数名指针和函数指针
2022-07-25 17:26:00 【wei2023】
函数名指针和函数指针
我们先来看一下函数指针式如何定义的,假如我们有一个函数int fun(int){…};那么他对应的函数指针写法就应该是int (*p)(int);然后再对他进行赋值,即p=fun;之后你就可以在接下来的地方按p作为函数名来调用它用起来完全和fun一样。(注意这里的p指针并不是只能接受fun这个函数名,任何返回值是int,参数只有一个int的函数都可以把函数名赋给p)
首先说一下C/C++在创建一个变量的时候比如int a;相应的在内存就会分配一个4个字节(根据不同机器可能不同)空间来存放这个int变量,而假设这4个字节的起始地址是0XFF0A,那么实际上就存在一种变量名和内存地址的映射,即a可以看做是一个标示符,他只是代表着0XFF0A这个地址,在程序中你对a进行的操作实际上也就是对内存中以0XFF0A为首地址的4个字节的操作,特别是如果对a进行取地址操作也就是&a实际上就是返回0XFF0A这个地址值,实际上你可以看成就是返回一个指向这个地址的指针(如果你觉的不能理解,就当我没说吧).同理对于我们在程序中创建的函数,他是保存在程序中的单独区域的,而我们调用它们就像使用变量一样需要一个地址来唯一的指向它,所以每个函数都需要一个地址来唯一标识自己(也就是我们常说的入口地址),就像上面的a对应0XFF0A,那么假设我们定义了一个int fun(int){};函数的入口地址是0XAAEE,则fun也就是函数名他会映射0XAAEE,和上面的int变量a一样如果对它进行取地址&fun的话就会返回0XAAEE,实际上fun也是一种类型,就当它是函数名类型好了,只要记住函数名本身并不是一个指针类型就可以了。
在调用函数的时候有函数名就够了,比如fun(2);不要以为只要有函数名就能调用函数了,其实这只是写法上的一个迷惑点,而编译器在编译的时候一律都会进行所谓的"Function-to-pointer conversion",也就是把函数名隐式转换成函数指针类型,也就是要通过函数指针来调用函数,所以如果你在调用函数的时候写成(&fun)(2)也是一样能工作的,因为&fun实际上就是返回一个函数指针,参照上一段中&a的例子,只是这种写法很不常见,即使你不显式的写出&的话编译器也会隐式的进行转换,注意&fun左右的括号必须有,这是因为运算符优先级的问题。
其实即使写成(fun)(2)也是可以正常运行的,这是因为当编译器看到fun的时候发现它前面没有&也就是没有给他显示的转换成指针那么他就要隐式的转换成指针,当转换完之后发现前面又有一个这时候也就是要进行所谓的"解引用"操作,也就是到*后面里指针里取出来值,而那么值实际上也就也就是0XAAEE也就是函数名fun,这么一次隐式换然后再来一次解引用实际上相当于什么也没做,所以系统还会再进行一次隐式的"Function-to-pointer conversion",即使你写成(*******fun)(2)也会正常运行,和刚才的一个道理,只是多做了几次反复的转解操作而已,都是编译器自己完成的,不必去理会!
例 1
#include<iostream>
using namespace std;
void fun(int a)
{
}
int main()
{
cout<<fun<<endl;
cout<<*fun<<endl;
cout<<&fun<<endl;
cout<<*****fun<<endl;
}
结果输出的值都是一样的,也就是都是指向同一个函数地址的指针值。
例 2
下面再结合自己定义的函数指针来看看
#include<iostream>
using namespace std;
int fun(int a)
{
cout<<"fun"<<endl;
return 0;
}
void main()
{
int(*p)(int)=fun;
int(*p1)(int)=*fun;
int(*p2)(int)=&fun;
p(1);
p1(1);
p2(1);
}
例 3
发现函数都能正常的运行,其实p1,p2,p和fun赋值之后大家一样理解就行了。接着上代码
#include<iostream>
using namespace std;
int fun(int a)
{
cout<<"fun"<<endl;
return 0;
}
void main()
{
int(*p)(int)=fun;
p(1);
// (&p)(1);
(*p)(1);
(****p)(1);
}
上面的程序也都会正常的运行,只要再理解的时候把p当成只是对函数名多做了一次转换就可以了,接下来理解都一样!注意上面注释掉的哪一行是不能运行的,因为p是我们自己定义的函数指针类型,如果你对指针取地址那么将得到p这个变量本身的地址,这就不能正确调用函数了!再多说一句,其实你如果运行&&fun这个式子也是非法的,至于为什么,大家一起帮我思考思考,我个人认为当我们运行&fun的时候他会转换成函数指针而实际上这个指针只是一个临时值而临时值是没有实际存放的内存地址的所以也就无法继续取地址了!
边栏推荐
- 博后招募 | 西湖大学机器智能实验室招聘博士后/助理研究员/科研助理
- With 8 years of product experience, I have summarized these practical experience of continuous and efficient research and development
- Is there a method in PostgreSQL that only compiles statements but does not execute them?
- Starting from business needs, open the road of efficient IDC operation and maintenance
- 第六章 继承
- C # introductory basic tutorial
- I want to manage money. I don't understand. Is there a principal guaranteed financial product?
- [knowledge atlas] practice -- Practice of question answering system based on medical knowledge atlas (Part3): rule-based problem classification
- EasyUI drop-down box, add and put on and off shelves of products
- Virtual memory management
猜你喜欢

Redis cluster deployment based on redis6.2.4
![[knowledge atlas] practice -- Practice of question and answer system based on medical knowledge atlas (Part5 end): information retrieval and result assembly](/img/47/e70f6b86f4dded3218370da7394a07.png)
[knowledge atlas] practice -- Practice of question and answer system based on medical knowledge atlas (Part5 end): information retrieval and result assembly

STM32 PAJ7620U2手势识别模块(IIC通信)程序源码详解

【硬件工程师】元器件选型都不会?

动态规划题目记录
![[mathematical modeling and drawing series tutorial] II. Drawing and optimization of line chart](/img/73/2b6fe0cf69fa013894abce331e1386.png)
[mathematical modeling and drawing series tutorial] II. Drawing and optimization of line chart

Outlook tutorial, how to search for calendar items in outlook?

With 8 years of product experience, I have summarized these practical experience of continuous and efficient research and development

第三章、数据类型和变量

EDI 对接CommerceHub OrderStream
随机推荐
Crawler framework crawler
虚拟内存管理
Summary of 80 domestic database operation documents (including tidb, Damon, opengauss, etc.)
stm32F407------SPI
Gtx1080ti fiber HDMI interference flash screen 1080ti flash screen solution
用秩讨论线性方程组的解/三个平面的位置关系
win10设备管理认不到GTX1080Ti 显示设备的解决办法
After consulting about how to deal with DDL in Flink SQL client, how to add fields and jobs to the mapping table in Fink SQL?
2022年最新北京建筑施工焊工(建筑特种作业)模拟题库及答案解析
Update 3dcat real time cloud rendering V2.1.2 release
8 年产品经验,我总结了这些持续高效研发实践经验 · 研发篇
做智能硬件要考虑的产品生命周期
服务器端架构设计期末复习知识点总结
What is metauniverse gamefi chain game system development? Development and application case and analysis of gamefi metauniverse NFT chain game system
爬虫框架-crawler
[target detection] yolov5 Runtong voc2007 dataset (repair version)
备考过程中,这些“谣言”千万不要信!
咨询下flink sql-client怎么处理DDL后,fink sql里面映射表加字段以及JOb?
第六章 继承
mindoc制作思维导图