指针几个有意思的面试题

题一:

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

考察知识点:
1.数组名为首元素的地址,给其进行+1操作其实就是指针向后走一步,也就是第二个元素的地址;
2.取地址数组名(&arr)取到的是整个数组的地址,虽然其指向的空间与数组名相同,但其所代表的意义不同。例如:取地址数组名+1,指针会走到数组后边的位置,因此对其进行-1操作,指针会走到数组最后一个元素的位置。
题二:

int main()
{
   int arr[4]={1,2,3,4};
   int *ptr1=(int*)(&arr+1);
   int *ptr2=(int*)((int)arr+1);  
   printf("%x,%x",ptr1[-1],*ptr2);//运行结果:4,2000000
   return 0;
}

考察知识点:
1.对指针使用下标来引用,相当于解引用操作。以上题为例相:(ptr1-1)=ptr[-1];
2.将数组名也就是首元素地址强转为int,在对其进行+1操作,相当于将指针向后移动了一个字节。然后再将其强转为(int
)的指针存放在ptr2这个指针中。而解引用操作会访问四个字节。
放到本题来理解就是,用int的四个字节存储了1的值,+1操作过后,指针走到了第二个字节的位置。然后用ptr2来保存这个位置。
具体请看下图:
在这里插入图片描述
题三

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

考察知识点:
1,括号内的逗号表达式结果为最后一个。在本题中(0,1)相当于1;
2.二维数组的数组名相当于第一行的地址。而数组名后只带一个下标则代表第一行的某一列的元素。
题四

int main()
{
   int aa=[2][5]={1,2,3,4,5,6,7,8,9,10};
   int *ptr1=(int*)(&aa+1);
   int *ptr2=(int*)(*(aa+1));
   printf("%d,%d",*(ptr1-1),*(ptr2-1));//运行结果:10,5
   return 0;
}

考察知识点参考题一
题五

int main()
{
  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;
}

考察知识点:
1.自加或自减(++,–)操作运行后会改变变量本身的值;
下图是对本体指针关系的一个解析:
变量定义完毕后各指针的指向位置
变量定义完毕后各指针的指向位置
在这里插入图片描述
第一个printf执行时和执行后指针的指向位置
在这里插入图片描述
第二个printf执行时和执行后指针的指向位置
题六

int main()
{
   int arr={1,2,3};
   int* p=a;
   printf("%d\n",*p++);//运行结果:1
   printf("%d\n",*++p);//运行结果:3
   return 0;
}

考察知识点:
1.后置的++虽然也可以改变指针的位置,但其返回值不会发生改变。
2.前置的++既改变了指针的位置也改变了其返回值。
因为1,所以在解引用之后打印的仍然是1,但第一个printf语句运行结束之后,指针p已经指向了2的位置。
因为2,所以指针会先指向3然后在解引用打印。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值