回调函数、(void *) 、 NULL -【操作系统源码阅读】

文章详细探讨了在学习操作系统时遇到的μC/OS-II源码中关于void*和NULL的区别,指出(void*)0是一个无参数类型的指针,需要类型转换才能赋值给其他指针类型。同时,文章解释了回调函数的概念和作用,通过示例说明如何使用函数指针参数来实现灵活的逻辑处理,减少代码修改量。在阅读源码时,这种技巧尤为重要。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

最近在学操作系统,实验课是阅读操作系统 μ C / O S − I I \mu C/OS- II μC/OSII 的源码,涉及到了一些指针的高级应用,于此做简要整理,并不断更新。

指针部分

void * 和 NULL的区别?

让我们看看编译器对NULL 的定义
在这里插入图片描述
宏定义有点难读,我觉得大概就是,NULL 的值在大部分情况下是 0, 而不是(void *)0,图中外面的大括号是为了保证整体性,防止宏替换时发生错误。那么 NULL 和 (void *)0 的区别是啥呢?
我写了下面这个程序:
在这里插入图片描述
编译器报错:
[Error] invalid conversion from ‘void*’ to ‘int*’ [-fpermissive]
也就是说(void *)0 是一个指针(可以理解为指向0地址的指针常量),无参数类型的指针,需要加类型强转才能赋值给(int *)。而NULL通常情况下等于0。
所以我们通常写的int *p = NULL 其实等价于int *p = 0,也就是p指向0地址。
举一反三:(void *)不能直接赋值给(int *)那反之可以吗?答案是肯定的。

void * 可以看作是所有指针类型的鼻祖, 祖先可以包容后代,而后代不可以包容祖先。(真是一代不如一代
有点类似于面向对象中的向上转型。

根据这个性质,在阅读源码时就能理解为啥函数参数为(void *)类型了。
··数据类型多种多样,可能是各种结构体,这时候传个指针就很方便的操作任意类型的数据。
在这里插入图片描述

回调函数、函数参数

回调函数是什么,有什么用?
举个例子:比如我们想写一个程序当 a > b 时 ,交换a , b
(虽然下面的程序完全不必要写的这么麻烦)

bool Bigger(int a, int b){
	return a > b;
}
void SwapAB(int a, int b){
	if(Bigger(a,b))
		swap(a,b);
}

过了一会,我们发现逻辑想错了,应该是a < b 交换 a, b

bool Smaller(int a, int b){
	return a < b;
}
void SwapAB(int a, int b){
	if(Smaller(a,b))
		swap(a,b);
}

观察上述过程,我们发现,在修改时,改了SwapAB的代码,又添加了Smaller函数,代码修改量大。而且在实际开发中,SwapAB的代码往往是透明的,无法直接修改。为了解决这个问题,函数参数与回调便出现了。
看下面代码,SwapAB中有一个函数参数,这个函数参数的名字是cmp(cmp其实是函数指针,指向函数的真正地址),返回值必须是bool类型,而且这个函数参数的参数必须是(int , int )。

bool cmp(int a, int b){
	return a < b;
}
void SwapAB(int a, int b, bool (*cmp)(int, int )){
	if(cmp(a,b))
		swap(a,b);
}

这样做有什么好处呢?当我们想再次修改cmp时,就不需要改动SwapAB的代码,而是直接改 cmp 函数就可以了。

这种把函数作为参数传递到主函数里面,主函数再调用的过程,就叫做回调。

看一下操作系统源码,果不其然,MyTask函数作为参数传进了OSTaskCreate()函数。
在这里插入图片描述

  • 函数指针变量
    阅读一下结构体的定义,cmp作为一个函数指针变量存在,这是以前没有见过的。
struct {
	int a;
	int b;
	bool (*cmp) (int, int);
}

未完待续…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值