c/c++指针:指针函数和函数指针


注意: 如果第一次接触指针,请点击下面这个链接,看完以后再来看这篇,以防直接劝退。
C语言指针基础

1.返回值是指针的函数

指针函数:
函数的返回值的类型既可以是整型(若没有设定,则默认为整型),字符型,等。当然也可以是指针类型。
返回值为指针类型的函数又称为指针类型的函数,简称指针函数

具体定义格式如下:
类型名 *函数名(参数表)

int *a(int x)
{
	printf("这个函数的返回值是指针");
	return NULL;//返回值为空指针
}
//解释一下
//这里函数名先和()结合,表示这是一个函数
//然后a()再和前面的*结合,表示这是一个指针类型的函数。
//最后与前面的int结合,表示这是int指针类型的函数,返回值是指针
 //(这个过程有点类似前面的指针数组,可以翻上去复习一下)
    

2.指向函数的指针变量(函数指针)重点

c语言的每个函数的编译的时候,都分配了一段连续的内存空间和一个入口地址,
这个入口地址就称为“指向函数的指针”即函数指针

可以用一个变量来存储函数指针,这个变量就称为“指向函数的指针变量”或者函数指针变量。

通过函数指针变量 就可以调用所指向的函数,改变它的值就可以动态调用不同的函数。

2.1 声明函数指针

类型说明符 (*变量名)()

注意:这种形式虽然看着奇怪,看着有点像定义函数,但是
但是,咱就是说但是,告诉自己,这是在声明一个指针,这个指针是
函数指针
,他还是个指针变量!!!!

举个例子:
在这里插入图片描述

int (*foo)();
//说明一下:
//foo先和*结合(括号的运算优先级高),表明该变量名是指针变量
//然后(*foo)后面的括号表示该指针变量指向一个函数
//最前面的int 表明这个函数返回值类型为Int
//这个变量foo是专门用来存放整型函数的入口地址的
  • 函数指针变量定义时,并不指向哪一个具体的函数,而是指向空指针。

再举几个函数指针的例子熟悉一下:

int (*ptr1)(double);
//定义一个函数指针ptr1,这个指针指向的函数有如下属性:
//返回值是int
//传入的参数是double

void (*ptr2)(char*);
//定义了一个函数指针ptr2,这个指针指向的函数又如下属性:
//返回值是void(空值,没有返回值)
//传入参数类型是字符指针

来吧,烧脑环节,区分一下下面这几个东西都是啥玩意?

int *ptr1();

int (*pt2)();

int* (*pt3)();

//揭晓答案
int *ptr1();
//这是在声明一个函数,这个函数具有如下属性:
//返回值:int*(int类型的指针)
//函数名:ptr1
//传入参数:无参数

int (*pt2)();
//这是在声明一个函数指针,这个函数指针所指向的函数具有如下属性:
//返回值:int
//传入参数:无
//函数名:肯定不知道呀,值知道指向函数的指针,函数名是不知道的,也不需要知道

int* (*pt3)(int*);
//好家伙,这个buff叠满了
//这是在声明一个函数指针,这个函数指针所指向的函数具有如下属性:
//返回值:int*(int类型的指针)
//传入参数:int*

2.2 使用函数指针

那如何通过函数指针变量调用函数呢?

那就是让函数指针变量p指向一个具体的函数,即将某个函数的入口地址赋值给这个指针变量。

那一般函数的入口地址在哪里呢?

函数名就代表函数的入口地址,是函数指针类型的符号常量。(这里和数组有点类似。)

那赋值给函数指针变量p以后,如何使用p来调用这个函数呢?

因为函数名本身就保存的是这个函数的入口地址,
所以,我们可以将函数名直接赋值给函数指针,
那么现在,这个函数指针就相当于是函数名了。
以前我们怎们用这个函数名调用函数,现在就怎们用这个函数指针调用函数

具体看下面代码示例

int (*ptr1)();

int UsePointFunction()
{
    printf("这个函数是用函数指针调用的!");
}

ptr1 = UsePointFunction;//将函数UsePointFunction的值赋值给ptr1
ptr();//通过函数指针调用函数

代码运行结果
在这里插入图片描述

为了后面书写方便,我们给函数指针起个别名,类似**int (*ptr1)();**这样的写法太麻烦了。
那具体怎么操作呢?

typedef int (*Ptr)();

Ptr ptr1;

上面这行代码是啥意思呢?

以后要是想定义返回值为int,传入参数为空的函数指针,直接写ptr就行了。

同理,再举几个例子吧:

typedef void (*Ptr1)(int);
Ptr1 ptr;
//以后在想定义返回值为空,传入参数的函数指针直接写第二行就行了

typedef long (*Ptr2)(double);
Ptr2 ptr;
//以后要定义返回值为long,传入参数为double的函数指针,直接写第六行就行了

2.3 传递函数指针

直接看代码,这就和普通的变量传参是一模一样的,但是效果很神奇。

int add(int num1, int num2)
{
    return num1 + num2;
}

int subtract(int num1, int num2)
{
    return num1 - num2;
}

typedef int (*fptr)(int ,int);
int comput(fpt opt, int num1, int num2)
{
    return opt(num1, num2);
}

//直接将函数名add和subtract当做实参传入,
//则comput就会调用add和subtract
//这的太牛啦!!!
printf("%d\n", comput(add, 1, 2));
printf("%d\n", compute(subtract,5,6));
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

辛伯达岛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值