c语言指针面试题详解3 第40课

写代码,分析结果

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;
}

我们对代码进行解析

首先,我们创建数组a,数组a的元素个数为4,元素为1,2,3,4

&a表示数组的地址,数组的地址+1表示跳过整个数组,处于数组末尾的地址

我们将数组末尾的地址强制类型转化为int型的指针 我们创建整形指针ptr1接收这个整形指针

ptr[-1]可以这样表示 *(ptr-1) 表示数组最后一个元素,为4

a在这里表示首元素的地址 将其强制类型转化为整型再+1 a是1 这时候我们要画出内存的图像

01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 数组首元素的地址是01 00 00 00,我们将其强制类型转化为整型结果为1 整型+1就表示+1 我们将其转化为地址表示向后移动一个字节 所以(int)a + 1表示的元素为00 我们再将其强制类型转化为整形指针 赋给ptr2,*ptr2表示对ptr2解引用,向后访问四个字节,访问的地址是 00 00 00 02 因为是小端存储,所以对应16进位制实际上是0x 02 00 00 00,ptr1[-1]对应的16进位制的结果为0x4

#include<stdio.h>
int main()
{
	int a[3][2] = { (0, 1), (2, 3), (3, 4) };
	int*p;
	p = a[0];
	printf("%d", p[0]);
	return 0;
}

我们首先要注意,二维数组的元素内部并不是用{}连接的  而是用(),这里表示逗号表达式,逗号表达式(x,y,   n),逗号表达式的结果为最后一位a ,所以这里存进去的内容只有1,3,5,所以存进去的实际上是[1  3]

                                    [5   0]

                                    [0   0] 

int*p表示p是整型指针,p=a[0], ,a[0]表示为第一行数组的数组名,但他既没有被sizeof修饰,又没有取地址,所以这里表示首元素的地址,也就是1,我们进行打印,打印 p[0],我们可以将它看成*(p+0),表示数组首元素,所以我们打印的结果就为1

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;
}

我们创建一个二维数组,5行5列,表示为

x[() () () () () ]   [() () () () () ]   [() () () () () ]   [() m() () l() () ]   [() () y() () () ]

我们创建一个数组指针p,指针p指向的元素个数为4,类型为整型         

a是数组名,数组名表示首元素的地址,首元素应该是第一行,第一行的地址位于x处,把这个地址赋给p,这时候会发生警告,原因是a和p的类型不同,a的类型用代码表示的结果int(*)[5] 而p的类型为int(*)[4],类型不同,所以产生警告   p的地址也在x处

a[4][2]表示第五列第三行,在y处 p[4][2]表示*(*(P+4)+2)首先对p+4 解引用,因为p是数组指针,p+1跳过四个字节,一共跳过16个字节,位于点m处,(p+4)表示数组首元素的地址,再+2表示向后移动两个字节,再解引用,到达l处

&p[4][2] - &a[4][2]两个地址相减,表示中间的元素个数,一共差四个,相减为-4,所以%d打印的结果为-4,%p打印的是地址,地址如何表示呢?我们首先写出-4的源码反码补码

10000000000000000000000000000100源码

1111111111111111111111111111111111011反码

1111111111111111111111111111111111100补码

因为地址是无符号数,不存在源码反码补码,所以我们用补码表示地址

我们用16进制将补码表示出来

四个1可以用一个F表示,所以结果为

FFFFFFFC

所以结果为FFFFFFFC   -4

 如图所示

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值