C/C++函数指针深入探究

目录
  • 函数指针
  • 语法
    • 函数地址
    • 声明
    • 使用函数指针调用函数
  • 深入理解函数指针
  • 使用typedef 简化

函数指针

为什么要使用函数指针?

  • 调用的灵活性和通用性。

试想一下,我们在设计初期并不知道我们的函数的具体实现细节。例如,我们我们想要一个排序函数qsort,但是具体排序法则我们并不确定,是降序还是升序,采用什么算法都不清楚。这些问题是要在用户调用这个函数的时候才能够决定。于是调用者应该自己设计comparator函数,传给qsort函数。

  • 便于面向对象编程。

例如我们设计一个结构体apple。我们除了设计出苹果的属性比如,数量、重量、颜色外,我们还要定义关于苹果的操作,比如,吃掉,种植,这时候我们可以使用函数指针。然后我们以后调用这个结构体的时候,可以采用a.eat(&b)的方式调用函数。

typedef struct apple{
    int number;
    double weight;
    colorType color;
    //some operations
    bool (*eat)(struct apple*);
    bool (*plant)(struct apple*);
}apple;

语法

函数地址

函数的地址实际上就是函数名。这一点可以类比于数组。

声明

要声明指向特定类型的函数的指针,可以先编写这种函数的原型,然后用(*pf)代替函数名。或者采用C++11 的auto也能声明并初始化函数指针。

double pam (int);
//这是函数原型
double (*pf)(int);
//这是函数指针
auto pn=pam;
//定义并初始化函数指针

使用函数指针调用函数

double pam (int);
//这是函数原型
double (*pf)(int);
//这是函数指针
auto pn=pam;
//定义并初始化函数指针
pf=pam;
pam(4);
(*pf)(4);
(*pn)(4);

直接把函数地址(即函数名)赋值给函数指针就行了,注意特征标和返回类型必须相同。然后采用(*pf)(4)这样的方式调用函数。实际上,C++也允许这样子使用函数指针:

pf(4);//这种形式好看且实用,但是没有显示出 使用函数指针调用函数
pn(4);

深入理解函数指针

阅读这一篇幅,需要您熟练掌握,C语言中的指针。

//一些函数原型
const double* f1(const double ar[],int n);
const double* f2(const double *,int);
const double* f3(const double *,int);
//函数指针
const double* (*p1)(const double ar[],int n)=f1;
auto p2=f2;//感谢auto
//调用函数
cout<<(*p1)(av,3)<<*(*p1)(av,3);
cout<<p2(av,3)<<*p2(av,3);
//实际上 *p2(av,3)和*(*p2)(av,3)是一样的。不理解的看上面内容。
//包含3个函数指针的数组
const double* (*pa[3])(const double *,int)={f1,f2,f3};
//注意:
//1、[]优先级高于* 所以这是个数组不是指针。
//2、不能使用auto定义并初始化列表
auto pb=pa;
//既然已经声明了数组,数组名就是指针,采用auto可以定义初始化指针,这是合法的。
//调用函数
double x=*pa[0](av,3);
double y=*(*pb[1])(av,3);//由于[]优先级高于* 所以pb[1]是个函数指针。然后(*pb[1])就是调用函数了。
//更加深入
const double *(*(*pd)[3])(const double *,int) = &pa;
//首先把函数指针的壳子去掉即 const double *(* ···)(const double *,int),然后得到(*pd)[3]这里 pd先和* 结合 再和[]结合,所以pd是个指针,这个指针指向一个数组,这个数组的元素又是函数指针。
//是不是特别绕?
//感谢auto
auto pc=&pa;
//调用
(*pd)[0](av,3);
//pd是指向数组的指针,则(*pd)[0]就是数组的元素,数组的元素是函数指针,所以可以采用这种方式调用函数。
//或者采用  (*(*pd)[0])(av,3)调用函数也是等价的。
double z=*(*pd)[0](av,3);
//或者 采用 double z=*(*(*pd)[0])(av,3) 也是等价的

我们对于语法的了解不能仅仅潜于认识,对于这种const double *(*(*pd)[3])(const double *,int) = &pa; 我们不光要认识,更要会使用,再次重温一遍,我们想要一个指向数组的指针,这个数组里的元素是函数指针。

第一步,数组元素的类型是函数指针,所以壳子要有 const double *(* ···)(const double *,int)

第二步,指向数组的指针 (*pd)[3] ,由于[]比*优先级高,所以我们必须采用(),否则 *pd[3] 就是一个数组,数组的元素是指针。 第三步,结合得 const double *(*(*pd)[3])(const double *,int) = &pa

使用typedef 简化

typedef const double *(* p_fun)(const double *,int);
p_fun p1=f1;
p_fun pa[3]={f1,f2,f3};
p_fun (*pd)[3]=&pa;

typedef 使得代码量减少很多,而且更容易理解

到此这篇关于C/C++函数指针深入探究的文章就介绍到这了,更多相关C++函数指针内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C语言超详细讲解函数指针的运用

    目录 前言 计算器的例子 回调函数 转移表 前言 前面我们学习了各种各样的指针类型,有些指针可以说是稀奇百怪,特别是函数指针,有些朋友可能觉得,函数指针有些多余,调用函数为什么要用指针调用,直接调用不好吗? 接下来我们从具体的实例来回答同学们的问题,加深对函数指针的理解. 计算器的例子 接下来我们写一个简单的计算器程序,完成不同的计算功能比如加减乘除: #include <stdio.h> //相加函数 int add(int a, int b) { return a + b; } //相减函

  • c++ 函数指针相关总结

    下面随笔说明函数指针用法. 函数指针的定义: 定义形式: 存储类型 数据类型 (*函数指针名)() 含义: 函数指针指向的是程序代码存储区 函数指针的典型用途-----实现函数回调 通过函数指针调用的函数 例如将函数的指针作为参数传递给一个函数,使得在处理相似事件的时候可以灵活的使用不同的方法. 调用者不关心谁是调用者 需知道存在一个具有特定原型和限制条件的被调用函数. 获取函数指针: 函数的地址就是函数名,要将函数作为参数进行传递,必须传递函数名. 声明函数指针 声明指针时,必须指定指针指向的

  • C++函数指针的用法详解

    目录 C++函数指针详细理解 函数指针初识 函数指针作为形参使用 函数指针作为返回值 练习 总结 C++函数指针详细理解 函数指针初识 函数指针是指向函数的指针,并不等于函数,它能够执行函数的操作,可以跟指针变量一起来理解,其基本声明格式为: type (*ptrname)(形参列表); 例子,声明一个比较两个字符串大小的函数指针 bool (*cp)(const string s1, const string s2); 需要注意的是,不要去掉括号!!!如果去掉括号,含义就变成了返回一个bool

  • c++函数名指针和函数指针

    目录 前言 例 1 例 2 例 3 前言 我们先来看一下函数指针式如何定义的,假如我们有一个函数int fun(int){…};那么他对应的函数指针写法就应该是int (*p)(int);然后再对他进行赋值,即p=fun;之后你就可以在接下来的地方按p作为函数名来调用它用起来完全和fun一样.(注意这里的p指针并不是只能接受fun这个函数名,任何返回值是int,参数只有一个int的函数都可以把函数名赋给p) 首先说一下C/C++在创建一个变量的时候比如int a;相应的在内存就会分配一个4个字节

  • C语言深入浅出分析函数指针

    目录 我们先看一个代码: #include<stdio.h> void test() { printf("haha\n"); } int main() { printf("%p\n", test); printf("%p\n", &test); return 0; } 输出的是两个地址,函数名就是函数的地址 将函数的地址存起来: #include<stdio.h> void test() { printf(&quo

  • 一起来学习C++的函数指针和函数对象

    目录 函数指针 函数对象 总结 函数指针 以下是<cstdlib>库中的一个排序数组的方法qsort()的函数原型. void qsort (void* base, size_t num, size_t size, int (*compar)(const void*, const void*)); base -- 指向要排序的数组的第一个元素的指针. num -- 由 base 指向的数组中元素的个数. size -- 数组中每个元素的大小,以字节为单位. compar -- 用来比较两个元素

  • C++函数指针详解

    函数指针基础: 1. 获取函数的地址 2. 声明一个函数指针 3.使用函数指针来调用函数 获取函数指针: 函数的地址就是函数名,要将函数作为参数进行传递,必须传递函数名. 声明函数指针 声明指针时,必须指定指针指向的数据类型,同样,声明指向函数的指针时,必须指定指针指向的函数类型,这意味着声明应当指定函数的返回类型以及函数的参数列表. 例如: double cal(int); // prototype double (*pf)(int); // 指针pf指向的函数, 输入参数为int,返回值为d

  • C++ 函数指针详细总结

    目录 1.函数指针 1.1 获取函数地址 1.2 声明函数指针 1.3 函数指针传参 1.4 调用函数 2.函数指针进阶 1.函数指针 函数指针顾名思义,就是指向函数的指针. 和数据类似,C++当中函数也有地址,函数的地址是存储函数机器语言代码的内存地址.我们可以将另外一个函数的地址作为参数传入函数,从而实现函数的灵活调用. 1.1 获取函数地址 获取函数地址的方法非常简单,只要使用函数名(后面不跟参数和括号)即可.比如我们有一个函数叫做think,那么think()是调用函数拿到结果,而thi

  • C++函数指针与指针函数有哪些关系和区别

    目录 1. 函数指针 1.1 概念定义 1.2 声明方法 1.3 调用方法 1.4 函数指针作为函数参数 1.5 函数指针数组 2. 指针函数 2.1 概念定义 2.2 调用方法 3. 总结 1. 函数指针 1.1 概念定义 函数指针是指向函数的指针变量. 因此函数指针本质上是一个指针变量,只不过该指针变量指向函数.指针变量也可以指向整型变量.字符型.数组,也可以指向函数. C语言中,每一个函数都有一个入口地址,函数指针就指向函数的入口地址,可以通过函数指针来调用函数. 例如 :int (*fu

  • C/C++函数指针深入探究

    目录 函数指针 语法 函数地址 声明 使用函数指针调用函数 深入理解函数指针 使用typedef 简化 函数指针 为什么要使用函数指针? 调用的灵活性和通用性. 试想一下,我们在设计初期并不知道我们的函数的具体实现细节.例如,我们我们想要一个排序函数qsort,但是具体排序法则我们并不确定,是降序还是升序,采用什么算法都不清楚.这些问题是要在用户调用这个函数的时候才能够决定.于是调用者应该自己设计comparator函数,传给qsort函数. 便于面向对象编程. 例如我们设计一个结构体apple

  • C++中回调函数及函数指针的实例详解

    C++中回调函数及函数指针的实例详解 如何获取到类中函数指针 实现代码: //A类与B类的定义 class A { public: void Test() { cout << "A::Test()" << endl; } }; class B : public A { public: void Test() { cout << "B::Test()" << endl; } }; //定义类的成员函数指针 typedef

  • C语言中函数指针的三种使用方法总结

     C语言中函数指针的三种使用方法总结 在这里分享一下自己的心得,希望和大家一起分享技术,如果有什么不足,还请大家指正.写出这篇目的,就是希望大家一起成长,我也相信技术之间没有高低,只有互补,只有分享,才能使彼此更加成长. 定义方式:int (*p)(int x, int y); 实现代码: #include <stdio.h> int sum(int x, int y){ return x + y; } int reduce(int x, int y){ return x - y; } int

  • 深入学习C语言中的函数指针和左右法则

    通常的函数调用     一个通常的函数调用的例子: //自行包含头文件 void MyFun(int x); //此处的申明也可写成:void MyFun( int ); int main(int argc, char* argv[]) { MyFun(10); //这里是调用MyFun(10);函数 return 0; } void MyFun(int x) //这里定义一个MyFun函数 { printf("%d\n",x); } 这个MyFun函数是一个无返回值的函数,它并不完成

  • 浅谈在Swift中关于函数指针的实现

    Swift没有什么? 苹果工程师给我建的唯一一堵墙是:在Swift中没有任何办法获得一个函数的指针: 注意,C函数指针不会导入到Swift中(来自"Using Swift with Cocoa and Objective-C") 但是我们怎么知道这种情况下钩子的地址和跳到哪呢?让我们深入了解一下,并且看看Swift的func在字节码层面上的是什么. 当你给一个函数传递一个泛型参数时,Swift并没有直接传递它的地址,而是一个指向trampoline函数(见下文)并带有一些函数元数据信息

  • ASP GetRef 函数指针试探

    GetRef 函数 返回一个指向一过程的引用,此过程可绑定某事件. Set object.eventname = GetRef(procname) 参数 object 必选项.事件所关联的对象的名称. eventname 必选项.要与函数绑定的事件的名称. procname 必选项.该字符串中包含 Sub 或 Function 过程的名称,该过程与事件关联. 说明 GetRef 函数可以用来将 VBScript 过程 (Function 或 Sub) 与 DHTML (动态 HTML)页面中可用

  • 一般函数指针和类的成员函数指针深入解析

    函数指针是通过指向函数的指针间接调用函数.函数指针可以实现对参数类型.参数顺序.返回值都相同的函数进行封装,是多态的一种实现方式.由于类的非静态成员函数中有一个隐形的this指针,因此,类的成员函数的指针和一般函数的指针的表现形式不一样. 1.指向一般函数的指针函数指针的声明中就包括了函数的参数类型.顺序和返回值,只能把相匹配的函数地址赋值给函数指针.为了封装同类型的函数,可以把函数指针作为通用接口函数的参数,并通过函数指针来间接调用所封装的函数.下面是一个指向函数的指针使用的例子. 复制代码

  • C++中函数指针详解及代码分享

    函数指针 函数存放在内存的代码区域内,它们同样有地址.如果我们有一个int test(int a)的函数,那么,它的地址就是函数的名字,如同数组的名字就是数组的起始地址. 1.函数指针的定义方式:data_types (*func_pointer)( data_types arg1, data_types arg2, ...,data_types argn); c语言函数指针的定义形式:返回类型 (*函数指针名称)(参数类型,参数类型,参数类型,-); c++函数指针的定义形式:返回类型 (类名

  • C#委托所蕴含的函数指针概念详细解析

    原则: 1.函数指针,实际上是函数编码后的指令在内存中的首地址,在C++/C中,这个地址可以用函数名直接使用 一个函数调用另一个函数的时候,就可以把被调用函数以函数指针的形式作为参数传入 2.回调函数callback使用的技术就是函数指针: 回调函数就好像是一个中断处理函数,系统在符合你设定的条件时自动调用.为此,你需要做三件事: 1). 声明: 2). 定义: 3). 设置触发条件,就是在你的函数中把你的回调函数名称转化为地址作为一个参数,以便于DLL调用. 回调函数是应用程序提供给Windo

  • c++函数指针和回调函数示例

    1.函数指针 函数指针是一个指针,只是这个指针它不像普通的指针指向是是一个变量,此时它指向的是一个函数,也就是它存储的是一个函数的地址,如果我们改变它的值,让它所指向的地址由指向funA转变为指向funB,那么这个函数指针的作用就改变了. 2.回调函数 什么是回调函数呢?回调函数其实就是一个通过函数指针调用的函数!假如你把A函数的指针当作参数传给B函数,然后在B函数中通过A函数传进来的这个指针调用A函数,这就是回调机制.B函数就是回调函数. 3.函数指针的使用 3.1函数指针声明 typedef

随机推荐