【指针面试题】-还在为学过指针的理论只是不会实践吗??赶紧来看看这里讲解了许多指针的面试题,带你更好掌握指针!!!

🎇作者:小树苗渴望变成参天大树
🧨作者宣言:认真写好每一篇博客
🎊作者gitee:link
在这里插入图片描述


💥前言

各位友友们,我们又见面了,答应大家要更新的指针练习题他终于来了,让大家久等了,好,我们开始进入正题。


💦一、指针和数组面试题解析

我们先来补充一个知识点:数组名的意义:

  1. sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。
  2. &数组名,这里的数组名表示整个数组,取出的是整个数组的地址。
  3. 除此之外所有的数组名都表示首元素的地址。

💨1.1一维数组

//一维数组
int a[] = {1,2,3,4};
printf("%d\n",sizeof(a));//数组名单独在sizeof内部表示整个数组,所以计算的是在整个数组的大小,//4*4=16
printf("%d\n",sizeof(a+0));//数组名不是单独在sizeof内部,所以数组名代表首元素地址,a+0还是首元素地址,是地址就是4/8个字节//4/8
printf("%d\n",sizeof(*a));//数组名不是单独在sizeof内部,便是首元素地址,解引用是首元素,sizeof计算的是首元素的大仙,是整型,所以就为4个字节//4
printf("%d\n",sizeof(a+1));//数组名不是单独在sizeof内部,所以数组名代表首元素地址,a+1就是第二个元素的地址,是地址就是4/8个字节//4/8
printf("%d\n",sizeof(a[1]));//a[1]表示数组的第二个元素,计算的是一个整型数的大小,所以是4个字节//4
printf("%d\n",sizeof(&a));//&a取出的整个数组的地址,也是地址,大小为4/8个字节//4/8
printf("%d\n",sizeof(*&a));//&a取出的是整个数组的地址,在进行解引用得到整个数组,大小为16个字节,取地址在解引用等于*&a=a,相当于在sizeof内部单独放了个数组名//16
printf("%d\n",sizeof(&a+1));//&a取出的是整个数组的地址,加1跳过整个数组的地址,是地址就是4/8个字节//4/8
printf("%d\n",sizeof(&a[0]));//&a[0]取出的是数组第一个元素的地址,是地址,大小为4/8个字节//4/8
printf("%d\n",sizeof(&a[0]+1));//&arr[0]取出的是数组第一个元素的地址在加1就是指向数组第二个元素的地址,是地址,大小为4/8个字节。//4/8

特别说明sizeof不存在非法访问的情况,1他不会使用你越界的那块地址,他的运行在编译截断就会完成,我们目前知道就行了,不需要过多去研究。

运行结果:
在这里插入图片描述


💢1.2字符数组

//字符数组
char arr[] = {'a','b','c','d','e','f'};
printf("%d\n", sizeof(arr));//数组名单独在sizeof内部,表示整个数组,所以大小为6个字节。//6
printf("%d\n", sizeof(arr+0));//arr不是单独在sizeof内部,所以表示首元素的地址加0还是表示首元素的地址,是地址就是4/8个字节//4/8
printf("%d\n", sizeof(*arr));//arr不是单独在sizeof内部,所以表示首元素的地址,在解引用表示首元素,因为是char类型,所以大小为1个字节//1
printf("%d\n", sizeof(arr[1]));//arr[1]表示数组的第二个元素,大小为1个字节//1
printf("%d\n", sizeof(&arr));//&arr表示整个数组的地址,是地址就是4/8个字节//4/8
printf("%d\n", sizeof(&arr+1));//&arr取出的是整个数组的地址,加1跳过整个数组的地址,是地址就是4/8个字节//4/8
printf("%d\n", sizeof(&arr[0]+1));//&arr[0]取出的是数组第一个元素的地址在加1就是指向数组第二个元素的地址,是地址,大小为4/8个字节。//4/8


size_t strlen(const char* str)


printf("%d\n", strlen(arr));//因为arr表示首元素地址,strlen只有看到\0才会停止下来,所以这个答案是随机值//随机值
printf("%d\n", strlen(arr+0));//arr+0也是表示第一个元素的地址,答案也是随机值//随机值
//printf("%d\n", strlen(*arr));//arr表示数组第一个元素的地址,在解引用表示数组第一个元素,但是strlen只能接收地址,所以会报错//error
//printf("%d\n", strlen(arr[1]));//同上一个//error
printf("%d\n", strlen(&arr));//&arr虽然是数组的地址,但是也是从数组起始位置开始的,计算的还是随机值//随机值
printf("%d\n", strlen(&arr+1));//&arr是数组的地址,&arr+1是跳过整个数组的地址,求字符串长度也是随机值//随机值
printf("%d\n", strlen(&arr[0]+1));//&arr[0] + 1是第二个元素的地址,是'b'的地址,求字符串长度也是随机值//随机值

运行结果:
在这里插入图片描述


char arr[] = "abcdef";//这是一个字符数组,后面默认会有一个\0,在计算数组大小的时候\0算字符串内容,但在计算长度的时候不算在字符串长度内。

printf("%d\n", sizeof(arr));//数组名单独在sizeof内部,计算的是整个数组的大小,所以大小为7个字节//7
printf("%d\n", sizeof(arr+0));//arr不是单独放在sizeof内部,所以arr表示数组名首元素的地址,arr+0也表示数组首元素的地址,是地址大小就是4/8个字节//4/8
printf("%d\n", sizeof(*arr));//arr不是单独放在sizeof内部,所以arr表示数组名首元素的地址,在进行解引用的是得到的首元素,sizeof计算的是一个字符类型的元素大小,所以大小为1个字节//1
printf("%d\n", sizeof(arr[1]));//arr[1]表示数组第二个元素,计算一个字符类型元素的大小,也为1个字节//1
printf("%d\n", sizeof(&arr));//&arr取出的是整个数组的地址,是地址就是4/8个字节//4/8
printf("%d\n", sizeof(&arr+1));//&arr取出的是整个数组的地址,加1跳过整个数组的地址,是地址就是4/8个字节//4/8
printf("%d\n", sizeof(&arr[0]+1));//&arr[0]取出的是数组第一个元素的的地址,加1指向数组的第二个元素的地址,是地址就是4/8个字节//4/8


printf("%d\n", strlen(arr));//arr是数组首元素的地址,从首元素开始计算字符串的长度,到\0停止,所以长度为6//6
printf("%d\n", strlen(arr+0));//arr是数组首元素的地址,arr+0也是数组首元素的地址,所以长度为6//6
printf("%d\n", strlen(*arr));//arr是数组首元素的地址,*解引用得到了首元素a,需要传地址过去,所以会报错//error
printf("%d\n", strlen(arr[1]));//同上一个//error
printf("%d\n", strlen(&arr));//&arr取到的整个数组地址的大小,和首元素的地址大小是相同的,所以计算的长度是6//6
printf("%d\n", strlen(&arr+1));//&arr取到的整个数组地址的大小,加1跳过整个数组,因为后面的空间不知道是啥样的,不知道啥时候找到\0,因为不会访问后面的空间,所以不会出现非法访问,所以这题的长度为随机值//随机值
printf("%d\n", strlen(&arr[0]+1));//&arr[0]取到的是数组首元素的地址,加1跳过一个元素,指向第二个元素的地址,所以从第二个元素开始计算字符串长度,所以长度为5//5

运行结果:
在这里插入图片描述


char *p = "abcdef";//这是一个字符指针用来存取字符串的地址的,p里面保存的是字符串首元素的地址,原因是,有首元素的地址就能找整个字符串,因为有\0作为结束标志。


printf("%d\n", sizeof(p));//p是指针,保存的是地址,是地址大小就为4/8个字节//4/8
printf("%d\n", sizeof(p+1));//p是首元素的地址,p+1指向第二个元素的地址,是地址,大小为4/8个字节
printf("%d\n", sizeof(*p));//p是首元素的地址,*解引用得到首元素a,a是一个字符类型,计算大小为1个字节//1
printf("%d\n", sizeof(p[0]));//同上一个//1
printf("%d\n", sizeof(&p));//&p是取出来的指针变量的地址,是地址,大小就是4/8个字节//4/8
printf("%d\n", sizeof(&p+1));//&p + 1是跳过p变量后的地址,4/8字节
printf("%d\n", sizeof(&p[0]+1));//p[0]就是‘a’,&p[0]就是a的地址,+1,就是b的地址,是地址就是4/8


printf("%d\n", strlen(p));//p是首元素的地址,从这个位置开始计算字符串长度,因为有\0作为结束标志,所以长度为6//6
printf("%d\n", strlen(p+1));//p是首元素的地址,+1指向的是b的地址,从b开始计算长度,为5//5
printf("%d\n", strlen(*p));//*p为元素,应该传地址,所以会报错//error
printf("%d\n", strlen(p[0]));//同上一个//error
printf("%d\n", strlen(&p))//&p拿到的是p这个指针变量的起始地址,找不到\0,所以从这里开始求字符串长度是随机值//随机值
printf("%d\n", strlen(&p+1));//&p+1是跳过p变量的地址,从这里开始求字符串长度也是随机值//随机值
printf("%d\n", strlen(&p[0]+1));//&p[0] + 1是b的地址,从b的地址向后数字符串的长度是5//5

运行结果:

在这里插入图片描述


💤1.3二维数组

//二维数组
int a[3][4] = {0};
printf("%d\n",sizeof(a));//数组名单独在sizeof内部,计算的是整个数组的大小,为4*3*4=48//48
printf("%d\n",sizeof(a[0][0]));//a[0][0]是数组第一行第一个元素,所以大小为4个字节//4
printf("%d\n",sizeof(a[0]));//a[0]表示的是数组第一行的地址,是单独放在sizeof内部,计算的是第一行全部元素的大小,为4*4=16个字节//16
printf("%d\n",sizeof(a[0]+1));//a[0]作为第一行的数组名,没有单独放在sizeof内部,没有取地址,表示的就是数组首元素的地址,那就是a[0][0]的地址,a[0]+1就是第一行第二个元素的地址,是地址就是4/8个字节//4/8
printf("%d\n",sizeof(*(a[0]+1)));//*(a[0] + 1)是第一行第2个元素,计算的是元素的大小-4个字节//4
printf("%d\n",sizeof(a+1));//a是二维数组的数组名,数组名表示首元素的地址,就是第一行的地址,a+1就是第二行的地址,第二行的地址也是地址,是地址就是4/8  //4/8
printf("%d\n",sizeof(*(a+1)));//a+1是第二行的地址,*(a+1)表示的就是第二行,*(a+1)--a[1]  //16
printf("%d\n",sizeof(&a[0]+1));//&a[0]是第一行的地址,&a[0]+1是第二行的地址,地址的大小就是4/8//4/8
printf("%d\n",sizeof(*(&a[0]+1)));//*(&a[0] + 1) 是对第二行的地址解引用,得到的就是第二行,计算的就是第二行的大小//16
printf("%d\n",sizeof(*a));//a表示首元素的地址,就是第一行的地址,*a就是第一行,计算的就是第一行的大小//16
printf("%d\n",sizeof(a[3]));//如果数组存在第四行,a[3]就是第四行的数组名,数组名单独放在sizeof内部,计算的是第四行的大小//16

运行结果:
在这里插入图片描述

🎄二、指针面试题

第一题:

int main()
{
    int a[5] = { 1, 2, 3, 4, 5 };
    int *ptr = (int *)(&a + 1);
    printf( "%d,%d", *(a + 1), *(ptr - 1));
    return 0;
}
//程序的结果是什么?

详细图解:
在这里插入图片描述
运行结果:
在这里插入图片描述


第二题:

//由于还没学习结构体,这里告知结构体的大小是20个字节
struct Test
{
 int Num;
 char *pcName;
 short sDate;
 char cha[2];
 short sBa[4];
}*p;
//假设p 的值为0x100000。 如下表表达式的值分别为多少?
//已知,结构体Test类型的变量大小是20个字节
int main()
{
 printf("%p\n", p + 0x1);
 printf("%p\n", (unsigned long)p + 0x1);
 printf("%p\n", (unsigned int*)p + 0x1);
 return 0;
}

详细图解:
在这里插入图片描述

运行结果:
在这里插入图片描述


第三题:

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

详细图解:
在这里插入图片描述

运行结果:
在这里插入图片描述


第四题:

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

详细图解:
在这里插入图片描述

运行结果:

在这里插入图片描述


第五题:

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

详细图解:
在这里插入图片描述

运行结果:
在这里插入图片描述


第六题:

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));
    return 0;
}

详细图解:
在这里插入图片描述

运行结果:
在这里插入图片描述


第七题:

#include <stdio.h>
int main()
{
 char *a[] = {"work","at","alibaba"};
 char**pa = a;
 pa++;
 printf("%s\n", *pa);
 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);
 printf("%s\n", *--*++cpp+3);
 printf("%s\n", *cpp[-2]+3);
 printf("%s\n", cpp[-1][-1]+1);
 return 0;
}

详细图解:
在这里插入图片描述

运行结果:
在这里插入图片描述


💖三、总结

博主花了很长实间用图的放是来和大家讲解指针方面的练习题,希望读者能认真将这些题目弄懂,学会,才是关键,今天的内容很充实,大家可以细心去品味一下这些题目,查缺补漏。那我们今天的讲解就到此结束了,我们下篇再见

在这里插入图片描述

  • 10
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

橘柚!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值