C语言链表指针操作这么骚的吗,跪求大神讲解
本帖最后由 achild 于 2019-3-21 18:39 编辑如图是ucos的动态内存链表操作里面的一段。
改变尾部指针,一个是加,一个是减。
加的操作里面
pblk是一个一级指针,接收了之前的链表尾部指针。之后的*(void **)pblk,我理解是强制转化为二级指针,然后*+二级指针怎么就得到下一个单元的地址地址了?
减的也是这个地方不理解。
(三行代码的是加操作,两行的是减操作) (void **)pblk 就把pblk 定性为一个 指向指针 的 指针*(void **)pblk = xxx意思就是赋值给 pblk 指向的那个指针, 那这时候 它指向的指针 就指向了地址 xxx
愚见 不知道理解得对不对。 你要明白 mem block 是怎么 chain 起来的话,就会理解了。去看看 OSMemCreate 函数。
每一个 blk 的起始 4 个字节,存放着是一个指针,这个指针的值,是下一个 blk 的地址值,以此类推,最后一个 blk 存放 0 值,形成一个 chain。
不过话说回来,这代码写得不够好。 security 发表于 2019-3-21 19:14
你要明白 mem block 是怎么 chain 起来的话,就会理解了。去看看 OSMemCreate 函数。
每一个 blk 的起始 4...
那该怎么写才好呢 浮华一生 发表于 2019-3-21 18:54
(void **)pblk 就把pblk 定性为一个 指向指针 的 指针*(void **)pblk = xxx意思就是赋值给 pblk 指向 ...
拿那个三行代码分析,pblk是一个一级指针,被赋值为add1吧。
*(void**)pblk 不管怎么类型转换,* pblk也是等于*add1吧,
然后add1=add1,我哪错了,不明白啊 deadline2012 发表于 2019-3-21 19:17
那该怎么写才好呢
OSMemFreeList 可以命名为 OSMemFreeListHeader 之类的,
移动块操作,可以用GetNextBlk 之类替换。
其实,我是瞎说的,别当真{:lol:} security 发表于 2019-3-21 19:14
你要明白 mem block 是怎么 chain 起来的话,就会理解了。去看看 OSMemCreate 函数。
每一个 blk 的起始 4...
你这明显之前用过ucos啊,知道了结构,表示还是看不懂啊,链表的操作怎么一个类型转换就完成了啊! achild 发表于 2019-3-21 19:34
拿那个三行代码分析,pblk是一个一级指针,被赋值为add1吧。
*(void**)pblk 不管怎么类型转换,* pblk ...
没看过这个代码 你有完整代码吗pblk 声明 初值这些 security 发表于 2019-3-21 19:37
OSMemFreeList 可以命名为 OSMemFreeListHeader 之类的,
移动块操作,可以用GetNextBlk 之类替换。
其实 ...
这是ucos核心代码,不是我写的,给我讲讲吗。 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;
}
浮华一生 发表于 2019-3-21 19:38
没看过这个代码 你有完整代码吗pblk 声明 初值这些
两个函数里面的参数,一个是函数里自定义的,一个是传递参数 security 发表于 2019-3-21 19:42
写个类似,结合我上面 chain 的说明,体会一下。
就是这个,*(void **) 这个操作能解释一下吗,大神,我今晚会不会失眠就指望你了 achild 发表于 2019-3-21 19:53
就是这个,*(void **) 这个操作能解释一下吗,大神,我今晚会不会失眠就指望你了 ...
你把 void * 看成 int,去理解看看。
只不过这个地址存放的是一个 void * 类型的指针,而不是 int 类型的整数。
后续的再加一个 * 操作,就是取得指针的值了。 本帖最后由 浮华一生 于 2019-3-21 20:07 编辑
看错 security 发表于 2019-3-21 20:00
你把 void * 看成 int,去理解看看。
只不过这个地址存放的是一个 void * 类型的指针,而不是 int 类型的 ...
我好像理解错了,这个链表不管有没有数据,每个单元的前几个字节的地址指针都是有效的,*(void **)只是一个简单的类型转换,并没有什么骚操作,我今天好蠢啊 浮华一生 发表于 2019-3-21 20:05
看错
一场误会误会,还是这个链表结构没搞明白, achild 发表于 2019-3-21 19:53
就是这个,*(void **) 这个操作能解释一下吗,大神,我今晚会不会失眠就指望你了 ...
括号里是强制类型转换,即把某个东西强制转化成了二级指针。括号外面的*,是所谓的“解引用”操作符,目的是根据索引的地址得到实际数据,而在这个地方,得到的数据仍然是一个指针—一个一级指针。
页:
[1]