很奇妙的C指针操作

1. 请问以下代码预期会有怎样的结果?

#include <stdio.h>

int* p[2] = {&p[0], &p[1]};

int main()
{
        printf("%x, %x, %x, %x, %x, %x", p, *p, **p, p + 1, *(p + 1), **(p + 1));
        return 0;
}


程序正常运行,这是其中一次的运行结果

1149034, 1149034, 1149034, 1149038, 1149038, 1149038

也就是说p[0]存储的是p[0]的地址,对p[0]指向的地址取值是p[0],有点绕,不是吗?惊讶

而且,如下图所示,p[0]、p[1]的内容还是有效的。


2.  继续复杂很多的例子

例子简化至cpython的内存池管理实现

#include <stdio.h>


typedef unsigned char uint8_t;
typedef uint8_t block;


typedef struct pool_header *poolp;


struct pool_header {
	block *_padding;
	block *freeblock;                   /* pool's free list head         */
	poolp nextpool;       /* next pool of this size class  */
	poolp prevpool;       /* previous pool       ""        */
};


#define PTA(x)  ((poolp )((uint8_t *)&(usedpools[2*(x)]) - 2*sizeof(block *)))
#define PT(x)   PTA(x), PTA(x)


static poolp usedpools[4] = {
	PT(0), PT(1)
};


int main()
{
	printf("%x, %x, %x\n", usedpools[0], usedpools[0]->nextpool, usedpools[0]->prevpool);
	printf("%x, %x, %x\n", usedpools[2], usedpools[2]->nextpool, usedpools[2]->prevpool);
	return 0;
}

程序正常运行,这是其中一次的运行结果

da902c, da902c, da902c
da9034, da9034, da9034

也就是说

usedpools[0]->nextpool, usedpools[0]->prevpool 的值是usedpools[0]

内存结构示意图:


usedpools[0]->nextpool操作,相当于 

usedpools[0]->nextpool

= *(poolp)((int)usedpools[0] + 2*sizeof(block *)) 

= *(poolp)((int)&usedpools[0] - 2*sizeof(block *) + 2*sizeof(block *)) 

= *(poolp)(&usedpools[0])

usedpools[0]


usedpools[0]->prepool操作,相当于 

usedpools[0]->prepool

= *(poolp)((int)&usedpools[0]->nextpool + sizeof(poolp)) 

= *(poolp)(&usedpools[1])

usedpools[1] 

usedpools[0]


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值