C语言结构体指针与箭头运算符工作原理及ptr2->ptr1->ptr1=ptr2代码行疑问
C语言指针指向逻辑解答
前置运行状态(执行目标代码前的内存布局)
首先先修正原代码的小疏漏:结构体定义缺少struct关键字,正确定义应为:
struct str1 { int k; struct str1 * ptr1; };
在执行ptr2 -> ptr1 -> ptr1 = ptr2;之前,已经完成了两步内存申请:
- 第一步
ptr2 = (struct str1 *) malloc(sizeof(struct str1));:在堆中申请了第一个struct str1类型的内存块(下称节点A),指针ptr2直接指向节点A的起始地址 - 第二步
ptr2 -> ptr1 = (struct str1 *) malloc(sizeof(struct str1));:在堆中申请了第二个struct str1类型的内存块(下称节点B),节点A的ptr1成员被赋值为节点B的起始地址,即节点A的ptr1指向节点B
目标代码逻辑拆解
ptr2 -> ptr1 -> ptr1 = ptr2;可以按优先级从左到右拆解:
- 先取
ptr2->ptr1:得到节点B的起始地址 - 再取
ptr2->ptr1->ptr1:就是节点B自身的ptr1成员 - 赋值操作把
ptr2的值(也就是节点A的起始地址)写入节点B的ptr1成员
赋值完成后,两个结构体就形成了双向的循环关联:
- 节点A的
ptr1→ 节点B - 节点B的
ptr1→ 节点A
也就是一个只有两个节点的循环链表结构。
额外补充:后续指针转换的逻辑
后面代码里的p1 = (int *) ptr2 -> ptr1;和p2 = (int *) ptr2 -> ptr1 -> ptr1;是利用了C语言结构体的内存布局特性:结构体第一个成员的起始地址和结构体本身的起始地址完全重合,所以把结构体指针强转成第一个成员类型的指针后,解引用拿到的就是第一个成员k的值:
*p1等价于节点B的k*p2等价于节点A的k
内容的提问来源于stack exchange,提问作者Azqaf
相关产品推荐
相关产品推荐

