嵌入式:指针的指针、链表、UCOS 的 OSMemCreate 。
初看,UCOS 的 OSMemCreate 代码,感觉有点怪怪的,比如,把 指针指向的地址 强制转换成 指针的指针的指向地址 ?那转换后 指针的指针 又是什么?
void OSMemCreate (OS_MEM *p_mem,
CPU_CHAR *p_name,
void *p_addr,
OS_MEM_QTY n_blks,
OS_MEM_SIZE blk_size,
OS_ERR *p_err)
{
#if OS_CFG_ARG_CHK_EN > 0u
CPU_DATA align_msk;
#endif
OS_MEM_QTY i;
OS_MEM_QTY loops;
CPU_INT08U *p_blk;
void **p_link;
...
p_link = (void **)p_addr; /* Create linked list of free memory blocks */
p_blk = (CPU_INT08U *)p_addr;
loops = n_blks - 1u;
for (i = 0u; i < loops; i++) {
p_blk += blk_size;
*p_link = (void *)p_blk; /* Save pointer to NEXT block in CURRENT block */
p_link = (void **)(void *)p_blk; /* Position to NEXT block */
}
*p_link = (void *)0; /* Last memory block points to NULL */
(1)、p_link = (void **)p_addr; //把 p_addr 的值(即地址)赋给 p_link ,但是,类型不一样,所以 强制转换 。
(2)、p_blk = (CPU_INT08U *)p_addr; //强制转换,因为 p_addr 为 void* 形参 ,任意类型的指针。
(3)、loops = n_blks - 1u; //循环次数
(4)、for (i = 0u; i < loops; i++) { //循环
(5)、 p_blk += blk_size; //把地址增加 一个块空间 大小
(6)、*p_link = (void *)p_blk; //把自增后的地址,赋值给 *p_link ,即写入到 *(p_addr + blk_size )数组里,因为,在(1)把p_addr 地址给了p_link。
(7)、p_link = (void **)(void *)p_blk; //p_blk,是CPU_INT08U * 类型指针,所以,先强制转换成(void *)任意类型的,然后,再用(void **)强制转换,同1;
(8)、} //循环结束
(9)、*p_link = (void *)0; //在链表结尾赋NULL。
在这里,**p_link 无意义,因为 *p_link 相当于*(p_addr + loops * blk_size ),即 数组的值, 那**p_link (*值)是什么?如果这个值,刚好是32位且申请过的空间,如 0x12345678,那么**p_link,也许就有意义了?
还有,既然**p_link ,都没用到过,那是否用 一级指针 就行了?没必要用 二级指针?
于是用 Xcode 做了些测试,如下:
1、传统教科书式用法,c -> b ->a

2、模仿UCOS的方法,b[0]=(a的地址),b[1]=(a的地址+3)。
2-1、发现有问题,调了下发现,任意类型的指针void *,自增,只增加1?
后续:后来用MDK试了下,void *,不能++。编译器的原因吧。

2-2、试了下地址,增加一个指针大小,就可以了。在这里,sizeof(void *) = sizeof(long int *) = 8 。用MAC的Xcode测试的。
后续:这里应该 +sizeiof(long int) 比较好。

3、同样模仿UCOS的写法,区别于2,指针类型都用 long int * ,不用 void * 。
3-1、和2相反,用指针自增是对的。

3-2、和2相反,加一个指针大小是错的。

4、后来,想,既然UCOS,用了指针的指针,但都没用到**p_link,只用到一级指针,那我是否可以把p_link都参数都加上*,变成使用**p_link,和*p_link?
结果一开始就错了。编译没问题,语法没错误,但是,p_p_b没有指向任何地址,不能对*p_p_b赋值。

5、对4的修改,与UCOS写法一样用了指针的指针,**p_p_b 相当于**p_link。用**p_p_b来修改外面的数组,用p_p_b来指向不断自增的外面数组的地址,且不需要重复 p_p_b = &p_b(UCOS写法需要,见(7),因为,UCOS,相当于用一级指针,地址改变,需要重复赋地址,而,这里二级指针指向了一个一级指针,一级变,二级会跟踪)。

6、再细想,既然UCOS只用到一级指针的效果。那么我是否可以直接用1级指针。
后续:这里有误,本来的效果应该是p_b_1++,类似UCOS的写法,需要 for 不断的p_b_2 = p_b_1

至此,结束。
嵌入式:指针的指针、链表、UCOS 的 OSMemCreate 。的更多相关文章
- Linus:利用二级指针删除单向链表
Linus大神在slashdot上回答一些编程爱好者的提问,其中一个人问他什么样的代码是他所喜好的,大婶表述了自己一些观点之后,举了一个指针的例子,解释了什么才是core low-level codi ...
- 【转】Linus:利用二级指针删除单向链表
原文作者:陈皓 原文链接:http://coolshell.cn/articles/8990.html 感谢网友full_of_bull投递此文(注:此文最初发表在这个这里,我对原文后半段修改了许多, ...
- 复制带有random指针的单链表
如图1所示,有一条单链表,其节点除了有next指针外,还有一个random指针.random指针可指向单链表中的任意节点,包括它自身.random指针一旦指定,便不再更改.请设计算法,复制此单链表,并 ...
- 通过数组初始化链表的两种方法:指向指针的引用node *&tail和指向指针的指针(二维指针)node **tail
面试高频题:单链表的逆置操作/链表逆序相关文章 点击打开 void init_node(node *tail,char *init_array) 这样声明函数是不正确的,函数的原意是通过数组初始化链表 ...
- 转:Linus:利用二级指针删除单向链表
感谢网友full_of_bull投递此文(注:此文最初发表在这个这里,我对原文后半段修改了许多,并加入了插图) Linus大婶在slashdot上回答一些编程爱好者的提问,其中一个人问他什么样的代码是 ...
- C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | IT宅.com
原文:C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | IT宅.com C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | I ...
- Mark指针的指针(**)和链表使用(*&)
利用二级指针删除单向链表 彻底理解链表中为何使用指针的指针或者指针的引用 详解C++指针的指针和指针的引用
- 40深入理解C指针之---指针与单链表
一.指针与单链表 1.定义:通过使用指针将节点(结点)链接起来成为链表 2.节点(结点): 1).数据域:主要用来存储数据,可以基本数据类型,也可以是构造数据类型: 2).指针域:主要用来当前节点(结 ...
- golang中值类型的嵌入式字段和指针类型的嵌入式字段
总结: 1. 值类型的嵌入式字段,该类型拥有值类型的方法集,没有值指针类型的方法集 2. 指针类型的嵌入式字段,该类型拥有值指针类型的方法集,没有值类型的方法集,并且,该类型的指针类型也有值指针类型的 ...
随机推荐
- 什么是图像 -- opencv基础
opencv基础篇--到底什么是图像 什么是图像?英语中有两个单词来形容图像,一个是picture,一个是image.这两者虽然是形容同一个东西,但却又有着区别.picture代表实而有物的真实图像: ...
- struts2的基本配置
1.package标签下主要的点在namespace和name,extend上 extend 一般继承自struts-default.xml下,继承其拦截器及一些功能,这个已在本人的拦截器一文中有讲到 ...
- JS图片赖加载例子
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- CSS深入理解学习笔记之padding
1.padding与容器尺寸之间的关系 对于block水平元素:①padding值暴走,一定会影响尺寸:②width非auto,padding影响尺寸:③width为auto或box-sizing为b ...
- SQL Server2008宝典 全书代码
-- ============================================= -- Create database template -- ==================== ...
- Android 自定义圆形图表
<com...SignChartView android:id="@+id/signChart" android:layout_width="265dp" ...
- selenium(2.4.0)中不能导出web drive 代码
最近在学习selenium.要做web自动化测试.咱只会C# .就想了,这个测试用例要是能用C# 控制,保存起来,就可以以后自动运行了,不用每次点击运行了. 看了看它的文档,就开始试验了,录脚本折腾了 ...
- Win SDK 标准程序
//-Registering window class. //-Creating window. //-Creating message loop. //-Implement WndProc func ...
- 爬虫入门之urllib库详解(二)
爬虫入门之urllib库详解(二) 1 urllib模块 urllib模块是一个运用于URL的包 urllib.request用于访问和读取URLS urllib.error包括了所有urllib.r ...
- UIRecorder安装与使用
继vue单元测试,将进行vue的e2e测试学习. 学习点: 安装uirecorder 用工具(UI Recorder)录制测试脚本 测试脚本的回放 本文意在安装UI Recorder,并且利用该工具进 ...