achild 发表于 2019-3-21 18:38:31

C语言链表指针操作这么骚的吗,跪求大神讲解

本帖最后由 achild 于 2019-3-21 18:39 编辑


如图是ucos的动态内存链表操作里面的一段。
      改变尾部指针,一个是加,一个是减。
   加的操作里面
         pblk是一个一级指针,接收了之前的链表尾部指针。之后的*(void **)pblk,我理解是强制转化为二级指针,然后*+二级指针怎么就得到下一个单元的地址地址了?
    减的也是这个地方不理解。
(三行代码的是加操作,两行的是减操作)

浮华一生 发表于 2019-3-21 18:54:15

(void **)pblk   就把pblk 定性为一个 指向指针 的 指针*(void **)pblk = xxx意思就是赋值给 pblk 指向的那个指针, 那这时候 它指向的指针 就指向了地址 xxx   
愚见 不知道理解得对不对。   

security 发表于 2019-3-21 19:14:24

你要明白 mem block 是怎么 chain 起来的话,就会理解了。去看看 OSMemCreate 函数。
每一个 blk 的起始 4 个字节,存放着是一个指针,这个指针的值,是下一个 blk 的地址值,以此类推,最后一个 blk 存放 0 值,形成一个 chain。
不过话说回来,这代码写得不够好。

deadline2012 发表于 2019-3-21 19:17:11

security 发表于 2019-3-21 19:14
你要明白 mem block 是怎么 chain 起来的话,就会理解了。去看看 OSMemCreate 函数。
每一个 blk 的起始 4...

那该怎么写才好呢

achild 发表于 2019-3-21 19:34:52

浮华一生 发表于 2019-3-21 18:54
(void **)pblk   就把pblk 定性为一个 指向指针 的 指针*(void **)pblk = xxx意思就是赋值给 pblk 指向 ...

拿那个三行代码分析,pblk是一个一级指针,被赋值为add1吧。
*(void**)pblk 不管怎么类型转换,* pblk也是等于*add1吧,
然后add1=add1,我哪错了,不明白啊

security 发表于 2019-3-21 19:37:35

deadline2012 发表于 2019-3-21 19:17
那该怎么写才好呢

OSMemFreeList 可以命名为 OSMemFreeListHeader 之类的,
移动块操作,可以用GetNextBlk 之类替换。
其实,我是瞎说的,别当真{:lol:}

achild 发表于 2019-3-21 19:37:37

security 发表于 2019-3-21 19:14
你要明白 mem block 是怎么 chain 起来的话,就会理解了。去看看 OSMemCreate 函数。
每一个 blk 的起始 4...

你这明显之前用过ucos啊,知道了结构,表示还是看不懂啊,链表的操作怎么一个类型转换就完成了啊!

浮华一生 发表于 2019-3-21 19:38:21

achild 发表于 2019-3-21 19:34
拿那个三行代码分析,pblk是一个一级指针,被赋值为add1吧。
*(void**)pblk 不管怎么类型转换,* pblk ...

没看过这个代码 你有完整代码吗pblk 声明 初值这些

achild 发表于 2019-3-21 19:40:10

security 发表于 2019-3-21 19:37
OSMemFreeList 可以命名为 OSMemFreeListHeader 之类的,
移动块操作,可以用GetNextBlk 之类替换。
其实 ...

这是ucos核心代码,不是我写的,给我讲讲吗。

security 发表于 2019-3-21 19:42:28

achild 发表于 2019-3-21 19:37
你这明显之前用过ucos啊,知道了结构,表示还是看不懂啊,链表的操作怎么一个类型转换就完成了啊! ...

写个类似,结合我上面 chain 的说明,体会一下。
typedef void * pvoid_t;

#define GetNextFreeBlk(FreeListHeader)        (*(pvoid_t *)FreeListHeader)

void* OSMemGet(OS_MEM*pmem,
               INT8U   *perr)
{
        pvoid_t pHeaderBlk;

        pHeaderBlk = pmem->OSMemFreeList;
        pmem->OSMemFreeList = GetNextFreeBlk(pHeaderBlk);
        pmem->OSMemNFree--;

        return pHeaderBlk;
}

achild 发表于 2019-3-21 19:46:45

浮华一生 发表于 2019-3-21 19:38
没看过这个代码 你有完整代码吗pblk 声明 初值这些



两个函数里面的参数,一个是函数里自定义的,一个是传递参数

achild 发表于 2019-3-21 19:53:44

security 发表于 2019-3-21 19:42
写个类似,结合我上面 chain 的说明,体会一下。

就是这个,*(void **) 这个操作能解释一下吗,大神,我今晚会不会失眠就指望你了

security 发表于 2019-3-21 20:00:40

achild 发表于 2019-3-21 19:53
就是这个,*(void **) 这个操作能解释一下吗,大神,我今晚会不会失眠就指望你了 ...

你把 void * 看成 int,去理解看看。
只不过这个地址存放的是一个 void * 类型的指针,而不是 int 类型的整数。
后续的再加一个 * 操作,就是取得指针的值了。

浮华一生 发表于 2019-3-21 20:05:37

本帖最后由 浮华一生 于 2019-3-21 20:07 编辑


看错      

achild 发表于 2019-3-21 20:14:39

security 发表于 2019-3-21 20:00
你把 void * 看成 int,去理解看看。
只不过这个地址存放的是一个 void * 类型的指针,而不是 int 类型的 ...

我好像理解错了,这个链表不管有没有数据,每个单元的前几个字节的地址指针都是有效的,*(void **)只是一个简单的类型转换,并没有什么骚操作,我今天好蠢啊

achild 发表于 2019-3-21 20:15:47

浮华一生 发表于 2019-3-21 20:05
看错

一场误会误会,还是这个链表结构没搞明白,

zcllom 发表于 2019-3-21 21:27:41

achild 发表于 2019-3-21 19:53
就是这个,*(void **) 这个操作能解释一下吗,大神,我今晚会不会失眠就指望你了 ...

括号里是强制类型转换,即把某个东西强制转化成了二级指针。括号外面的*,是所谓的“解引用”操作符,目的是根据索引的地址得到实际数据,而在这个地方,得到的数据仍然是一个指针—一个一级指针。
页: [1]
查看完整版本: C语言链表指针操作这么骚的吗,跪求大神讲解