指针习题

1.一维数组

 2.字符数组

sizeof

strlen这个参数部分它要的是地址 如果你传一个元素  元素的ASCII码值被strlen读取

那么这是非法的 

 3.

4.

 5.

abcdef是一个常量字符串 

p是一个指针  因此它只可以存放4个字节的大小 

因此在p中只能存放常量字符串首元素a的地址 地址一般为4个或8个字节  32位为4个字节 64位为8个字节

如图所示 内存布局

 

重点在第五 六 七 这三个  

第五个  分析  p指向abcdef这个常量字符串 &p指向p 那么&p存放p的地址

它仍然是一个地址  那么sizeof(地址)==4或8字节

第六个  &p+1跳过整个p 但它仍然是一个地址

 6.

 7.二维数组

重点* 

a[0]相当于第一行的数组名  数组名单独放在sizeof中  表示的是整个数组的大小

那么sizeof(arr[0])相当于是求第一行所有元素的大小 即是4*4=16个字节

当sizeof(arr[0]+1)时 arr[0]不是表示第一行的地址了  因为它没有单独存在到sizeof()中

这个arr[0]代表的是第一行的首元素地址

sizeof(a[3])  分析

对于一个二维数组 给定一个a[3]表示第四行的地址

sizeof()这里计算的是一个类型  它并不关心你是否真实存在第四行   因为sizeof并不参与真实的计算的  所以这里a[3]会被当做a[0]即是二维数组第一行去计算大小 即是4*4=16个字节

8.

1.把地址强转成结构体指针类型 然后每次加一跳过结构体变量 20个字节的大小

0x00100000+0x1=0x00100000+20=0x00100014 十六进制

2.强制转化成长整型long的形式  每次加一  真的就是加一

0x00100000+0x1=0x00100001

3.同1  强制转化为整形指针类型 加0x1 跳过一个int类型的大小

结果为0x00100004

9.

本题的切入点在于 a的被强制类型转化为int整形 之后再加一 表示加一个字节

由于一个元素占据四个字节的空间大小 并且是小端存储  

从左到右地址依次升高 

如图  那么ptr2解引用 由于强制转化为int* 那么一次访问4个字节的大小 即是0x02000000

ptr[-1]=*(ptr-1) 同理被强制类型转化为整形指针类型 那么一次访问四个字节 即是0x00000004  

 

10.

a[0]没有单独放在sizeof内部 也没有& 

所以它代表第一行第一个元素的地址

逗号表达式 从左往右计算  并且结果是右边的那个数

那么相当于存储了1 3  5  其余位置默认为0

p[0]=*(p+0)=*(a[0])=1

11.

%p打印地址  默认-4的补码为1111111111111111111111111100  转化为16进制为0xfffffffc

%d打印结果为-4

两个地址相减结果就是两个地址之间的元素个数

a为一个二维数组 那么a表示第一行的地址

p=a相当于p一开始指向第一行的地址 即是指向首元素

p是一个数组指针类型 每一次加一 都相当于跳过4个元素大小的区域

p[4][2]=*(*(p+4)+2)

12.

 aa为二维数组名

&aa时 取出的是整个二维数组的地址 那么&aa+1跳过整个二维数组 再把它赋给ptr2

由于强制类型转化为int*类型 那么减一跳过一个int类型的区域大小 

aa 与&aa[0] 意义相同都是代表二维数组第一行的地址

那么*(aa+1)==aa[1] 由于这里的aa[1]前面没有& 也不是放在sizeof()里面

所以这里的aa[1]代表的是第二行首元素的地址

之后的步骤同前面差不多了 就这样吧

13.

p[1][2]==*(*(p+1)+2)==*(p[1]+2)

 14.重点题型 

首先我们得知 char**pa=a;

众所周知  *pa代表着它是一个指针 指向a  char*代表着被指向对象a的类型

char*a[ ]是一个指针数组 数组元素类型是char*

我们可知  work at 等这三个字符串都是常量字符串

那么我们可知  这个指针数组中的char*类型的三个元素分别保存着这三个字符串首字符的地址

那么分别指向这三个字符

14.最后一题 硬核压轴

先写第一部分的解析吧

如何画出这个图  char***cpp    *cpp代表cpp它是一个指针 指向cp  被指向的cp的类型是什么呢?是前面红色标记处 char**    cp是一个二级指针数组它的元素都是二级指针类型 那么理所应当的指向一级指针数组c     cp数组元素指向另外一个数组指针  这个数组指针 各个元素的内容即是相对应的常量字符串首元素的地址

1.cpp一开始指向c+3 先++指向c+2  c+2指向c中第三个元素的地址  第三个类型为char* 它包含着常量字符串POINT 首字符的地址 %s打印 打印结果是POINT

2.cpp是变化的  ++cpp 相当于cpp=cpp+1

cpp指向向下一个指向c+1 解引用得到c+1的内容 

c+1的内容是第二个char*的地址 

由于是得到了c+1的内容  是内容不是地址 

然后--  直接在内容上改 而不是直接改变它的指向 

那么c+1-1=c 如图所示即可  所以这时候它指向第一个char*的地址

再解引用得到第一个char*的内容

这个内容是 常量字符串ENTER的首字符的地址

3.先转化一下  即等价于 *(*(cpp-2))+3   

这里的-2 跟++  --  这些不一样 它不会改变cpp的值 即是不改变cpp的指向位置  但确实改变了结果的值  即是cpp的指向不发生改变

所以原来指向c+1    减二之后指向c+3

但是cpp的指向是一直指向c+1的  因为cpp-2 不是一个表达式  而是一个结果变化而已 

只有当cpp=cpp-2时 cpp的指向才会发生变化  

4.同理 可转化成*(*(cpp-1)-1)+1

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值