IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C/C++深入函数指针 -> 正文阅读

[C++知识库]C/C++深入函数指针

? ? ? ?下面通过一个示例演示如何更好使用函数指针。首先,如下是一些函数的原型,它们的特征标和返回类型相同:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5bCP5p6t56CB,size_20,color_FFFFFF,t_70,g_se,x_16
? ? ? ?这些函数的特征标看似不同,但实际上相同。首先,前面说过,在函数原型中,参数列表const double ar [ ]与const double * ar的含义完全相同。其次,在函数原型中,可以省略标识符。因此,const double ar [ ]可简化为const double [ ],而const double * ar可简化为const double *。因此,上述所有函数特征标的含义都相同。另一方面,函数定义必须提供标识符,因此需要使用const double ar [ ]或const double * ar。
? ? ? ? 接下来,假设要声明一个指针,它可指向这三个函数之一。假定该指针名为p1,则只需将目标函数原型中的函数名替换为(*p1):watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5bCP5p6t56CB,size_20,color_FFFFFF,t_70,g_se,x_16
? ? ? ?可在声明的同时进行初始化:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5bCP5p6t56CB,size_20,color_FFFFFF,t_70,g_se,x_16
? ? ? 使用C++11的自动类型推断功能时,代码要简单得多:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5bCP5p6t56CB,size_20,color_FFFFFF,t_70,g_se,x_16
? ? ? ?现在来看下面的语句:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5bCP5p6t56CB,size_20,color_FFFFFF,t_70,g_se,x_16
? ? ? ?根据前面介绍的知识可知,(*p1) (av, 3)和p2(av, 3)都调用指向的函数(这里为f1()和f2()),并将av和3作为参数。因此,显示的是这两个函数的返回值。返回值的类型为const double *(即double值的地址),因此在每条cout语句中,前半部分显示的都是一个double值的地址。为查看存储在这些地址处的实际值,需要将运算符*应用于这些地址,如表达式*(*p1)(av,3)和*p2(av,3)所示。
? ? ? ? 由于需要使用三个函数,如果有一个函数指针数组将很方便。这样,将可使用for循环通过指针依次调用每个函数。如何声明这样的数组呢?显然,这种声明应类似于单个函数指针的声明,但必须在某个地方加上[3],以指出这是一个包含三个函数指针的数组。问题是在什么地方加上[3],答案如下(包含初始化):

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5bCP5p6t56CB,size_20,color_FFFFFF,t_70,g_se,x_16
为何将[3]放在这个地方呢?pa是一个包含三个元素的数组,而要声明这样的数组,首先需要使用pa[3]。该声明的其他部分指出了数组包含的元素是什么样的。运算符[]的优先级高于*,因此*pa[3]表明pa是一个包含三个指针的数组。上述声明的其他部分指出了每个指针指向的是什么:特征标为const double *, int,且返回类型为const double *的函数。因此,pa是一个包含三个指针的数组,其中每个指针都指向这样的函数,即将const double *和int作为参数,并返回一个const double *。
这里能否使用auto呢?不能。自动类型推断只能用于单值初始化,而不能用于初始化列表。但声明数组pa后,声明同样类型的数组就很简单了:

0a80321f083b4fab8a058c84fd18c576.png
? ? ? ?数组名是指向第一个元素的指针,因此pa和pb都是指向函数指针的指针。
如何使用它们来调用函数呢?pa[i]和pb[i]都表示数组中的指针,因此可将任何一种函数调用表示法用于它们:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5bCP5p6t56CB,size_17,color_FFFFFF,t_70,g_se,x_16
? ? ? ?要获得指向的double值,可使用运算符*:?watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5bCP5p6t56CB,size_13,color_FFFFFF,t_70,g_se,x_16

? ? ? ?可做的另一件事是创建指向整个数组的指针。由于数组名pa是指向函数指针的指针,因此指向该数组的指针将是一个指向“指向数组指针的指针”的指针。这听起来有点恐怖,但由于可使用单个值对其进行初始化,因此可使用auto:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5bCP5p6t56CB,size_20,color_FFFFFF,t_70,g_se,x_16
? ? ? ?如果喜欢自己声明,该如何办呢?显然,这种声明应类似于pa的声明,但由于增加了一层间接,因此需要在某个地方添加一个*。具体地说,如果这个指针名为pd,则需要指出它是一个指针,而不是数组。这意味着声明的核心部分应为(*pd)[3],其中的括号让标识符pd与*先结合:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5bCP5p6t56CB,size_20,color_FFFFFF,t_70,g_se,x_16
? ? ? ? 换句话说,pd是一个指针,它指向一个包含三个元素的数组。这些元素是什么呢?由pa的声明的其他部分描述,结果如下:?watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5bCP5p6t56CB,size_20,color_FFFFFF,t_70,g_se,x_16

? ? ? ?要调用函数,需认识到这样一点:既然pd指向数组,那么*pd就是数组,而(*pd)[i]是数组中的元素,即函数指针。因此,较简单的函数调用是(*pd)i,而*(*pd)i是返回的指针指向的值。也可以使用第二种使用指针调用函数的语法:使用(*(*pd)[i])(av,3)来调用函数,而*(*(*pd)[i])(av,3)是指向的double值。
? ? ? ?请注意pa(它是数组名,表示地址)和&pa之间的差别。正如您在本书前面看到的,在大多数情况下,pa都是数组第一个元素的地址,即&pa[0]。因此,它是单个指针的地址。但&pa是整个数组(即三个指针块)的地址。从数字上说,pa和&pa的值相同,但它们的类型不同。一种差别是,pa+1为数组中下一个元素的地址,而&pa+1为数组pa后面一个12字节内存块的地址(这里假定地址为4字节)。另一个差别是,要得到第一个元素的值,只需对pa解除一次引用,但需要对&pa解除两次引用:

18d28b90da004a58b71477176366ab8b.png

?

?

?

?

?

?

?

?

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-05-18 17:26:01  更:2022-05-18 17:26:10 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 18:52:04-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码