C语言面试题---指针篇(四)

版本声明:本文转载于公众号TeachPlus

C语言面试题---指针篇(四)

数组,从来都是考察指针最好的载体,所以数组与指针结合的考题是最多的,下面的题目就是通
过指针和数组结合来考察指针的:

    
    
  1. # include <stdio.h>
  2. int main( void)
  3. {
  4. int a[ 5]={ 1, 2, 3, 4, 5};
  5. int *ptr=( int *)(&a+ 1);
  6. printf( "%d,%d",*(a+ 1),*(ptr -1));
  7. return 0;
  8. }
输出结果是什么呢?

本题解析

答案:输出结果为2,5
*(a+1)  就是 a[1]  , *(ptr-1)  就是 a[4]  ,执行结果就是2,5
&a+1  不不是首地址+1,系统会认为加一个a数组的偏移,
是偏移了一个数组的大小(本例是5个int)
int *ptr=(int *)(&a+1)  ;则ptr实际是 &(a[5])  ,也就是 a+5

原因如下:
&a  是数组指针,其类型为  int (*)[5]  ;
而指针加1要根据指针类型加上一定的值,不同类型的指针+1之后增加的大小不同。
a是长度为5的int数组指针,所以要加  5*sizeof(int)  ,所以ptr实际是 a[5]  。
但是 prt  与 (&a+1)  类型是不一样的(这点很重要),所以 prt-1  只会减去 sizeof(int*)
a,&a  的地址是一样的,但意思不一样,a 是数组首地址,也就是 a[0] 的地址,
 &a 是对象(数组)首地址,a+1  是数组下一元素的地址,即 a[1]  , &a+1  是下一个对象的地址,即 a[5]。

相关知识点

接下来看这样的一道题目,会对于上面的题目的理解更加深刻一点:
数组int c[3][3];为什么c,*c的值相等,(c+1),(*c+1)的值不等c,*c,**c,代表什么意思?

解析:

首先看最后一个问题, c  是第一个元素的地址, *c  是第一行元素的首地址,其实第一行元素的
地址就是第一个元素的地址, **c  是提取第一个元素。
为什么 c  , *c  的值相等?
c是数组名,是一个二维指针,它的值就是数组的首地址,也即第一行元素的首地址(等于 *c  ),
也等于第一行第一个元素的地址( &c[0][0]  );可以说成是二维数组的行指针。
*c  是第一行元素的首地址;是一个一维指针,可以说成是二维数组的列指针。
**c  :二维数组中的第一个元素的值;即:c[0][0]
所以:c 和 *c的值是相等的,但他们两者不能相互赋值,(类型不同)

综上所述, (c+1)  与 (*c+1)  中:
(c+1)  ,c是数组名也就是二维数组的行指针,所有 c+1  是移动一行,
将指针指向二维数组中第二行的首地址,也就是 &c[1][0]  .
而 (*c+1)  中, *c  是二维数组第一行的首地址,也就是二维数组的列指针,所以 (*c+1)  ,
移动的是一列,是将指针指向二维数组第一列的第二个元素,也就是 &c[0][1]
在这里,还需要提醒的一点就是所谓的数组指针和指针数组:

    
    
  1. char (* str)[ 20]; /*str是一个数组指针,即指向数组的指针.*/
  2. char * str[ 20]; /*str是一个指针数组,其元素为指针型数据.*/
再看一道题目巩固一下:

    
    
  1. # # include <stdio.h>
  2. int main()
  3. {
  4. int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8};
  5. int *p=arr;
  6. *(p++)+= 123;
  7. printf( "%d,%d\n", *p,*(++p));
  8. return 0;
  9. }
在本题中:
第一行,定义数组 arr  ,元素共八个
第二行,定义指针 p  指向 arr  数组,此时的 *p  还是等于 arr  数组的第0个元素,也就是1。
第三行, p++  里的++是最后才运算,所以先执行 *p+=123  ,也就是arr的第0个元素被赋值为123。
此时arr变成{123,2,3,4,5,6,7,8} ,然后是 p++  ,此时 *p  已经是等于arr的第1个元素了了,也就是2。
第四行,在执行 printf  时,括号里的参数是从右往左的顺序进行读取的,也就是说先执行  *(++p)  ,
也就是p先加一再指针,指向的是 arr  第2个元素3,然后再执行 *p  ,还是3。
最后显示的内容就是:3,3



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值