浅谈C/C++函数指针与异步回调机制

23 篇文章 3 订阅
12 篇文章 0 订阅

函数指针与指针函数

先来看两种声明:

int* fun(int i);
int (*fun)(int i);

首先明确,前者为指针函数,后者为函数指针,他们的区别就在于:

  1. 一个返回值类型为int型指针的函数
  2. 一个指向返回值类型为int的函数的指针

也就是说函数指针可以将函数变成一个类似与变量的东西供我们操作

两者的用法实例:
1.

#include<stdio.h>
#include<stdlib.h>

int* fun(int i)
{
	return ((int*)malloc(i)); 
	/*
	申请一块动态内存,以指针的形式返回,等价于
	int* p = (int*)malloc(i);
	return p;
	*/
}

int main(int argc,char* argv[])
{
	int* p = fun(sizeof(int));
	*p  = 1;
	printf("%d",*p);
	free(p);
	return 0;
}

指针函数可以将一个指针变量作为返回值

#include<stdio.h>
#include<stdlib.h>

int fun(int i)
{
	printf("num %d",i);
	return 0;
}

int main(int argc,char* argv[])
{
	//这里也可以将参数部分的变量名写上去,没有什么区别int (*pfun)(int i) = fun;
	int (*pfun)(int) = fun;
	pfun(2); //这里调用的是函数指针pfun,不是函数fun
	return 0;
}

函数指针可以将一个函数地址存入指针,之后通过调用该指针来达到调用函数的目的

异步回调机制

什么是回调?对于对windows编程与js比较了解的同鞋肯定都知道,但为了照顾不了解的同鞋,我还是来简单介绍一下.

从函数的调用方式来讲,可以分为三类:同步调用、回调、异步调用。
同步调用是一种阻塞式调用,调用方要等待对方执行完毕才返回,它是一种单向调用;
回调是一种双向调用模式,也就是说,被调用方在接口被调用时也会调用对方的接口;
异步调用是一种类似消息或事件的机制,不过它的调用方向刚好相反,接口的服务在收到某种讯息或发生某种事件时,会主动通知客户方(即调用客户方的接口)。回调和异步调用的关系非常紧密,通常我们使用回调来实现异步消息的注册,通过异步调用来实现消息的通知。
同步调用是三者当中最简单的,而回调又常常是异步调用的基础

通常我们直接的去调用函数算是一种同步调用,同步调用最大的特点,我个人认为就是你的函数去主动的调用其他函数. 而异步回调机制恰恰相反, 它是你的函数被动的被其他函数所调用

函数指针的作用

说完以上部分,就再来距举例说明一下函数指针的作用
假想场景:
假设你在项目中负责编写一个函数A, 这个函数B的功能是:

  1. 循环检查, 每一分钟检查一次进程1是否还在运行,
  2. 将进程1的运行状态通过参数传递给另一个函数
  3. 将状态写入日志文件

以上场景 , 可能会存在多个解决方法, 但这里就利用异步回调的方式来解决一下这个问题
伪代码:

//将函数指针以函数参数的形式进行传递
void A(void (*fun)(int status))
{
	while(1)
	{
		//获取进程1的状态代码......
		fun(以整数形式代表的进程1的状态);
		Sleep(1000*60);
		//写入日志文件
	}
}

不同程序员编写的调用函数A的函数:
程序员a:

void callback(int status)
{
     if(status)
	//如果发现进程1正在运行, 那就向服务端A发送一条消息
}

int getStatus()
{
	A(callback);
	return 0;
}

程序员b:

void oneProcess(int status)
{
     if(status)
	//如果发现进程1没有在运行,那就创建进程1
}

int checkProcess()
{
	A(oneProcess);
	return 0;
}

因为我们的函数会不停的去循环检查,所以无法通过返回值的形式来向调用者反馈进程1的状态, 在加上可能会有多个不同的函数利用我们的函数来获取进程1的状态来进行不同的操作

除此之外,接触过socket编程的同学肯定知道, 服务端在listen后会将accept放置在一个死循环里用于接受客户端的套接字, 假如说我们正在封装一个TCP通信库, 想要把accept接受到的客户端套接字通过返回值的形式传递给第三方调用者明显是不现实的, 但是如果利用了回调机制,那就会变得很容易.

  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在CLR/C++中,可以使用函数指针来引用和调函数。以下是使用CLR/C++定义和使用函数指针的示例: ```cpp #include <iostream> // 定义函数指针类型 typedef void (*FunctionPointer)(int); // 示例函数1 void Function1(int value) { std::cout << "Function1 called with value: " << value << std::endl; } // 示例函数2 void Function2(int value) { std::cout << "Function2 called with value: " << value << std::endl; } int main() { // 声明函数指针变量 FunctionPointer fp; // 将函数指针指向函数1 fp = &Function1; // 调用函数1 fp(10); // 将函数指针指向函数2 fp = &Function2; // 调用函数2 fp(20); return 0; } ``` 在这个示例中,我们首先使用`typedef`定义了一个函数指针类型`FunctionPointer`,该函数指针可以指向一个接受一个`int`参数并返回`void`的函数。 然后,我们定义了两个示例函数`Function1`和`Function2`,它们符合上述的函数指针类型。 在`main`函数中,我们声明了一个名为`fp`的函数指针变量。 我们将`fp`指向`Function1`并调用它,然后将`fp`指向`Function2`并再次调用它。 当我们调用函数指针时,实际上是在调用指向的函数。 请注意,CLR/C++中的函数指针与传统的C++函数指针有所不同,需要使用`typedef`定义函数指针类型,并使用`&`操作符来获取函数的地址。此外,CLR/C++还支持其他类型的委托和函数对象,可以更灵活地处理函数回调和事件处理。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值