初看,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 。的更多相关文章

  1. Linus:利用二级指针删除单向链表

    Linus大神在slashdot上回答一些编程爱好者的提问,其中一个人问他什么样的代码是他所喜好的,大婶表述了自己一些观点之后,举了一个指针的例子,解释了什么才是core low-level codi ...

  2. 【转】Linus:利用二级指针删除单向链表

    原文作者:陈皓 原文链接:http://coolshell.cn/articles/8990.html 感谢网友full_of_bull投递此文(注:此文最初发表在这个这里,我对原文后半段修改了许多, ...

  3. 复制带有random指针的单链表

    如图1所示,有一条单链表,其节点除了有next指针外,还有一个random指针.random指针可指向单链表中的任意节点,包括它自身.random指针一旦指定,便不再更改.请设计算法,复制此单链表,并 ...

  4. 通过数组初始化链表的两种方法:指向指针的引用node *&tail和指向指针的指针(二维指针)node **tail

    面试高频题:单链表的逆置操作/链表逆序相关文章 点击打开 void init_node(node *tail,char *init_array) 这样声明函数是不正确的,函数的原意是通过数组初始化链表 ...

  5. 转:Linus:利用二级指针删除单向链表

    感谢网友full_of_bull投递此文(注:此文最初发表在这个这里,我对原文后半段修改了许多,并加入了插图) Linus大婶在slashdot上回答一些编程爱好者的提问,其中一个人问他什么样的代码是 ...

  6. C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | IT宅.com

    原文:C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | IT宅.com C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | I ...

  7. Mark指针的指针(**)和链表使用(*&)

    利用二级指针删除单向链表 彻底理解链表中为何使用指针的指针或者指针的引用 详解C++指针的指针和指针的引用

  8. 40深入理解C指针之---指针与单链表

    一.指针与单链表 1.定义:通过使用指针将节点(结点)链接起来成为链表 2.节点(结点): 1).数据域:主要用来存储数据,可以基本数据类型,也可以是构造数据类型: 2).指针域:主要用来当前节点(结 ...

  9. golang中值类型的嵌入式字段和指针类型的嵌入式字段

    总结: 1. 值类型的嵌入式字段,该类型拥有值类型的方法集,没有值指针类型的方法集 2. 指针类型的嵌入式字段,该类型拥有值指针类型的方法集,没有值类型的方法集,并且,该类型的指针类型也有值指针类型的 ...

随机推荐

  1. python词频统计

    1.jieba 库 -中文分词库 words = jieba.lcut(str)  --->列表,词语 count = {} for word in words: if len(word)==1 ...

  2. mysql应用学习-解决数据乱码

    原因 mysql数据库character_set_database和character_set_server默认编码是latin1,所以导致乱码: 修改步骤 step1. 修改my.ini配置 在[m ...

  3. 项目管理系统 TAIGA 部署

    题记 使用了 MantisBT 一段时间,觉得功能太少,只局限在错误跟踪,而且操作体验比较差,界面很糟糕,很早就想将其换掉. 偶然发现一个很不错的新选择:Taiga,于是就试着将其部署下来,发现绝对是 ...

  4. centos-7.2 node.js免编译安装

    cd /usr/local/ wget https://npm.taobao.org/mirrors/node/v8.9.3/node-v8.9.3-linux-x64.tar.gz tar -zxv ...

  5. PHP性能检测与优化—XHProf 数据阅读

    PHP性能检测与优化—XHProf 数据阅读 一.      效果如下 请求总揽 函数调用情况 二.      参数含义 Inclusive Time              包括子函数所有执行时间 ...

  6. vue 路由权限

    import Vue from 'vue' import Router from 'vue-router' import HelloWorld from '@/components/HelloWorl ...

  7. iPython与notebook的基本用法

    1 Ipython 安装 pip install ipython 2 Notebooke 基本用法 启动ipython使用ipython 启动notebook 使用 ipython notebook ...

  8. day006-多线程

    1. 线程概念 a)     什么是主线程 Java程序启动过程中自动创建的并执行main方法的线程称为主线程 主线程的执行路径: 从main方法开始到main方法结束 b)什么是子线程 除了主线程的 ...

  9. SASS初体验

    SASS初体验 标签(空格分隔): sass scss css 1. 编译环境 需要安装Ruby,之后需要打开Start Command Prompt with Ruby运行 gem install ...

  10. 遍历目录树 - Unicode 模式

    =info     遍历目录树 支持 Unicode     Code by 523066680@163.com     2017-03         V0.5 使用Win32API判断目录硬链接 ...