指针相关练习

1.写出打印之后的结果?

int main()
{
	int a[5] = { 1, 2, 3, 4, 5 };
	int *ptr = ( int * )(&a + 1);
	printf("%d,%d", *(a + 1), *(ptr - 1));
	return 0;
}

答案是:2,5

首先初始化数组,&a表示取出整个数组的地址(切记),&a+1 表示在跳过整个数组,来到下个数组首元素地址的位置,因为要存在整型指针 *ptr中,所以进行强制类型转化;*(ptr-1)表示第一个数组最后一个元素的 位置,解引用也就是5;*(a+1):a既没有sizeof,也没有&a,所以在此a表示首元素的地址,a+1 解引用表示第二个元素,也就是2,所以最终答案是  2, 5;

2. 假设 p 的值为0x100000。如下表达式的值分别是多少?

已知:结构体Test类型的变量大小是20字节;

struct Test
{
	int Num;
	char *pcName;
	short sDate;
	char cha[2];
	short sBa[4];
}*p;
//p=0x100000
int main()
{
	p = (struct Test*)0x100000;//p 是指针类型,需要强制类型转换为结构体类型;
	printf("%p\n", p + 0x1);
	printf("%p\n", (unsigned long)p + 0x1);
	printf("%p\n", (unsigned int*)p + 0x1);
	return 0;
}

答案是:00100014       00100001         00100004

首先: p 初始化值为0x100000,%p表示打印地址,+0x1表示在基础之上+1;0x是十六进制位的前缀,p是结构体指针,p+1表示加上一个结构体的大小(字符+1表示加上一个字符的大小),题目说明结构体的变量大小为20个字节,p=0x100000+20=0x100014(14的意思是该指针数十六进制位,4*16^0+1*16^1=14)补全十六进制位的8位是0x00100014;

第二个:表示整型p+1,直强制类型转换为整型,就是实实在在的在p=0x100000基础之上+1=0x00100001;

第三个:强制类型转化为一个无符号指针 unsigned int*;无符号指针+1表示跳过一个无符号指针的大小;直接在p的基础之上+4即可=0x00100004;

总结:指针+整数 的大小 取决于 指针的类型;不同指针的类型所加整数值的大小不同;

3. 计算下面的值:

int main()
{
	int a[4] = { 1, 2, 3, 4 };
	int *ptr1 = (int *)(&a + 1);
	int *ptr2 = (int *)((int)a + 1);
	printf("%x,%x", ptr1[-1], *ptr2);
	return 0;
}

答案是:4 , 2000000

首先:初始化数组a[4];*ptr1的意思是取出a的整个数组地址(&a),在此基础之上+1表示跳过整个数组的大小;来到下一个数组第一个元素的地址; ptr1[-1]   等价于  ptr1-1也就是第一个数组最后一个元素的地址;

a 的32位地址为:01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00;

a表示首元素的地址;a强制类型转换为整型,(int)a+1 直接在整型的基础上+1;来到第二位,强制类型转换为整型,访问8个字节,得到02 00 00 00;

4.

int main()
{
	int a[3][2] = { (0, 1 ), ( 2, 3 ),(4, 5)};
	int *p;
	p = a[0];
	printf("%d", p[0]);
	return 0;
}

答案是:1;

首先:数组初始化中放的是括号表达式,而不是大括号的数组元素,需要特别注意;

括号表达式的结果是括号里面的最后一个元素,所以在二维数组[3][2]中的元素是1 3 5 0 0 0六个元素;p[0]表示的是首元素的地址解引用,所以答案是1;

5.,仔细思考:

int main()
{
	int a[5][5];
	int(*p)[4];
	p = a;
	printf("%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);
	return 0;
}

 答案是:   FFFFFFFC,   -4

 首先:初始化二维数组a[5][5],如下图所示;&a[4][2]:我们先找到a[4],也就是第五行元素,a[4][2]表示第五行下角标为2的元素;如图所示:

把a强制给到指针p,p表示首元素地址;&p[4][2]等价于取出*(*(p+4)+2);而指针p表示数组指针,每个指针指向的数组含有4个元素;然后每四个向后+1;找到p[4]的位置如图所示;解引用得到的元素指向首元素的地址;(p+4)+2得到图中绿色所示的地址;

两个地址相减的结果是两个地址所指向位置之间的元素个数;也就是4;但是显然&a的地址在&p的地址之前,所以是-4

%p打印地址:得到32位字节的补码形式;-4的补码如下:

100000000000000000000000000000100---原码

1111111111111111111111111111111111011---反码

1111111111111111111111111111111111100---补码   转换成16进制位:每四个是一个F

所以是FFFFFFFC

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值