前言
一些关于指针理解的题目
题目一
//假设p的值为0x100000.如下表达式的值为多少
//已知,结构体test的变量大小是20个字节
struct test
{
int num;
char* pcname;
short sdate;
char cha[2];
short sba[4];
}*p;
int main(void)
{
printf("%p\n", p + 0x1);// p指向结构体指针,p + 1 跳了20个字节,= 0x100014
printf("%p\n", (unsigned long)p + 0x1);//p转换为无符号长整型 p+1 = 0x100001
printf("%p\n", (unsigned int*)p + 0x1);//p为无符号整型指针 p + 1 跳了4字节 = 0x100004
return 0;
}
解释
- p是结构体指针,p+1 类似 int* p = &arr ,p+1跳过一个数组,此时p+1则跳过一个结构体, 而本题结构体大小为20字节,故p的值加上20(十进制)为 0x100014 (十六进制)
注:内存单位是字节,每相邻两个地址编号之间相差1字节
题目二
int main(void)
{//32位,小端存储
int a[4] = { 1,2,3,4 };
int* ptr1 = (int*)(&a + 1);// &a + 1 为4后面空间的地址,转换为int*,
int* ptr2 = (int*)((int)a + 1);// 0x4 0x2000000
printf("%#x %#x", ptr1[-1], *ptr2);
return 0;
}
解释
小端存储:低位字节存放在内存的低地址端,高位字节存放在内存的高地址端
如:int a = 0x1223344;
存储为:(低地址端) 44 33 22 01 (高地址端)
题目三
int main(void)
{
char* c[] = { "ENTER", "NEW", "POINT", "FIRST" };
char** cp[] = { c + 3,c + 2,c + 1,c };
char*** cpp = cp;
printf("%s\n", **++cpp);// POINT
printf("%s\n", *-- * ++cpp + 3); // ER
printf("%s\n", *cpp[-2] + 3); //ST
printf("%s\n", cpp[-1][-1] + 1); //EW
return 0;
}