C++:函数指针 & 返回函数指针的函数

函数指针 & 返回函数指针的函数

一、函数指针的声明和使用

声明一个函数指针,给它赋值并调用它指向的函数

函数指针就是一个指向函数的指针。

先来简单看一下怎么使用函数指针。我们声明一个函数,和一个指向该函数类型的指针,让指针指向该函数并通过指针调用它。

#include<iostream>
using namespace std;

//定义一个返回值为int、参数表为(char,double)的函数
int func(char c, double d) {
    cout << c << " = " << d << endl;
    return 0;
}

int main() {
    //p_int是一个指向返回值为int、参数表为(char,double)的函数的指针
    int (*p_int)(char, double);
    //让p_int指向函数func
    p_int = &func;
    //通过函数指针p_int调用func
    (*p_int)('A',3.14);
    return 0;
}

输出结果:A = 3.14

可以这样描述p_int:它指向一个返回值为int、参数表为(char,double)的函数。声明函数指针的句子是int (*p_int)(char, double),我们可以这样理解它:

  • p_int前面的*说明它是一个指针
  • (*p_int)的右侧是一个形参表,这说明该指针指向一个函数
  • (*p_int)的左侧是int,这说明该指针指向的返回值是int类型

注意(*p_int)两侧的括号不能省略,否则句子就会变成int *p_int(char,double),这是一个函数,函数名为p_int,返回值是一个int型指针。

p_int的值为0nullptr时,说明它不指向任何函数。

等价的表达

(1)在给函数指针赋值时,以下语句作用是相同的:

p_int = &func;
p_int = func;

第一个的句子意义很显然:把函数func的地址赋给p_int;而由于我们把函数名当作一个值使用时,它会自动地转换成指针,则第二个的句子也做了一样的事情。

(2)在使用函数指针调用函数时,以下语句作用是相同的:

(*p_int)('A',3.14);
p_int('A',3.14);

不论是对p_int解引用还是直接使用p_int,都可以成功地调用它指向的函数。

二、函数指针作为形参传递

函数的形参列表中不能定义函数类型的形参,所以要把一个函数作为另一个函数的参数需要使用函数指针类型的形参:

#include<iostream>
using namespace std;

//定义一个返回值为int、参数表为(char,double)的函数
int func(char c, double d) {
    cout << c << " = " << d << endl;
    return 0;
}

//定义一个函数,形参列表中包含func这一类型的函数
void use_pointer_of_func(char c, double d,int (*p)(char,double)) {
    p(c,d);
}

int main() {
    //把func作用参数调用
    use_pointer_of_func('A', 3.14, &func);
    //写作use_pointer_of_func('A', 3.14, func)也是可以的
}

在函数use_pointer_of_func的形参列表中,int (*p)(char,double)就是一个函数指针类型的形参。然而如果(*p)指向的函数形参列表很长,如int (*p)(char,double,double,double,char,char,char.......),这时候可以用decltypetypedef来简化语句:

typedef decltype(func) *F;
//写作typedef int (*F)(*char c, double d)也是等价的
void use_pointer_of_func(char c, double d, F) ......

更改后代码如下:

#include<iostream>
using namespace std;

//定义一个返回值为int、参数表为(char,double)的函数
int func(char c, double d) {
    cout << c << " = " << d << endl;
    return 0;
}

typedef decltype(func)* F;
//写作typedef int (*F)(*char c, double d)也是等价的

//定义一个函数,形参列表中包含func这一类型的函数
//F是func类型的函数指针的别名
void use_pointer_of_func(char c, double d, F p) {
    p(c, d);
}

int main() {
    //把func作用参数调用
    use_pointer_of_func('A', 3.14, &func);
    //写作use_pointer_of_func('A', 3.14, func)也是可以的
}

三、返回值为函数指针类型的函数

以上说了函数本身不能作为形参,同样的,函数也不能作为返回值,但是我们可以返回指向函数的指针。以下是一个名为f的函数,它的参数表是(string),它返回一个函数指针,指向一个参数表为(char,double)返回值为int的函数:

int (*f(string))(char, double);

我们来理解一下这个语句:

  • f有形参列表(string),所以f是一个输入参数为一个字符串的函数
  • f前面有*,说明f返回的是一个指针
  • 指针(*f(int))右侧有形参列表(char, double),说明f返回的指针指向一个函数,(char, double)是该函数的形参表。
  • 最左边的int说明被指向的函数返回值是int类型

上面的写法有点绕,我们可以用using来简化它:

using F = int(char,double);
F *f(string);

该写法与int (*f(string))(char, double)等价,并且含义较容易理解:函数f读入一个string参数返回一个F*类型的值,而F是一个读入参数表(char,double),返回一个int的函数。

你也可以直接把F作为函数指针:

using F = int(*)(char,double);//F是函数指针类型
F f(string);//f的返回类型是函数指针
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,222评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,455评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,720评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,568评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,696评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,879评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,028评论 3 409
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,773评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,220评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,550评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,697评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,360评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,002评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,782评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,010评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,433评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,587评论 2 350

推荐阅读更多精彩内容