• 指针笔试题~走近大厂


    前言

    作者小蜗牛向前冲

    名言我可以接收失败,但我不能接收放弃

     如果觉的博主的文章还不错的话,还请点赞,收藏,关注👀支持博主。如果发现有问题的地方欢迎❀大家在评论区指正。


    目录

    笔试题1:

    笔试题2

     笔试题3

     笔试题4

     笔试题5

    笔试题6 

     笔试题7

    笔试题 8

     总结

     下面我将为大家分享几道指针的笔试题,希望大家能有所收获。

    笔试题1:

    1. #include<stdio.h>
    2. int main()
    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. }

    这道题的结果如何呢?

    对于指针类型的题目,我们最好的解题方式是画图,下面所以有的指针题目我将都会用图来为大家解惑。 


    a数组元素的分布图


     从图中我们可以看出指针ptr指向的是数组a之外的元素

    a是数组名-->首元素的地址。

    那么我们(a+1)不就是从首地址跳过一个元素,指向下个元素的地址,*(a+1)就找到了元素2。

    那么(ptr-1)左移动一个整形的大小,指向5这个元素,*(ptr-1)便找到这个元素。

    所以我们的结果为2,5.

    笔试题2

    1. struct Test
    2. {
    3. int Num;
    4. char *pcName;
    5. short sDate;
    6. char cha[2];
    7. short sBa[4];
    8. }*p;
    9. //假设p 的值为0x000000。 如下表表达式的值分别为多少?
    10. //已知,结构体Test类型的变量大小是20个字节
    11. int main()
    12. {
    13. printf("%p\n", p + 0x1);
    14. printf("%p\n", (unsigned long)p + 0x1);
    15. printf("%p\n", (unsigned int*)p + 0x1);
    16. return 0;
    17. }

    首先我们要明白p是什么,p是一个结构体指针,%p值的是打印出指针的地址,我们可以假设p的地址为0x000000,那么p+0x1又表示什么呢?其实就是将p+20-->0x000014

    其中(unsigned long)p,将指针p强制类型转化为整形,所以(unsigned long)p+0x1-->0x000001。

    其次(unsigned int*)p,这影响的是指针+-跳过的字节数,其中ungsing int*的大小为4字节,所以 (unsigned long)p + 0x1-->0x000004。

     笔试题3

    1. int main()
    2. {
    3. int a[4] = { 1, 2, 3, 4 };
    4. int* ptr1 = (int*)(&a + 1);
    5. int* ptr2 = (int*)((int)a + 1);
    6. printf("%x,%x", ptr1[-1], *ptr2);
    7. return 0;
    8. }

     


    a数组的内存分布图


    这里我们先理解清楚,ptr1和ptr2都是int *类型的指针。

    (&a + 1)表示跳过整个数组,指向数组后面的元素。

    (int)a将a转化为整形,(int )a+1表示a的值加1,就指针跳过1个字节(如图的位置)。

    %x指以十六进制打印。

    好了我们理解清楚这些变量名的意义了,就开始解题吧。

    ptr1[-1]- ->*((&a+1)-1),也就是说解引用指向数组最后位置的指针,就找到了元素0x4.

    *ptr2,就是找到ptr2指针指向的元素,根据内存的存取规则,要倒这取出来-->02 00 00 00 ,所以屏幕中最终打印的值为2 00 00 00。

     笔试题4

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

     


    a数组元素的分布图


     这道题目其实是有个坑,大家误认为初始化为

    0 1

    2 3

    4 5

    这种形式,其实()是个,号表达式,输出的值右括号最后的值。所以根据上面的数组元素分布图,我们的出p[0]-->*(p+0)的值为。

     笔试题5

    1. int main()
    2. {
    3. int a[5][5];
    4. int(*p)[4];
    5. p = a;
    6. printf("%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);
    7. return 0;
    8. }

    a数组的元素分布图 


    这里我们理解a是什么?p又是什么?&p[4][2]和&a[4][2]表示什么?

    其中a为二维数组,a的类型为int(*)[4],p为数组指针,p的类型为int(*)[4]。

    &a[4][2],图中黄色方块为a[4][2]指向的元素。

    p[4][2]-->&*(*(p+4)+2),首先P+4指向图中的位置,为什么呢?可能会人有有疑问,因为p认为自己指向的是4个int类型,所以每次+1都会跳过4个整形元素。其次,在(*(p+4)+2),*(p+4)就会访问4个整形的数组,数组名+就会跳过2个元素,指向第3个元素,在*(*(p+4)+2)就会找到第3个元素(图中绿色方块)。

    所以, &p[4][2] - &a[4][2](指针-指针)=指针于指针之间的元素个数4,因为是第地址的指针-高地址的指针结果为-4.

    -4

    原码:10000000 00000000 00000000 00000100

    反码:11111111 11111111 11111111 11111011

    补码:1111 1111 1111 1111 1111 1111 1111 1100

    十六进制:F   F     F        F     F      F      F       C

    %p打印FFFFFFFC。

    %d打印-4。

    笔试题6 

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

    aa数组的元素分布图


     这道题和笔试题1及其相似的,把图画出来后就很好解题了。

    ptr1-1-->指向aa[1][4],*(prt1-1)找到10。

    ptr2-1-->指向aa[0][4],*(ptr2-1)z找到5。

     笔试题7

    1. #include <stdio.h>
    2. int main()
    3. {
    4. char *a[] = {"work","at","alibaba"};
    5. char**pa = a;
    6. pa++;
    7. printf("%s\n", *pa);
    8. return 0;
    9. }

     a与pa的内存分布


     

     这里我们同样画好图,pa是个二级指针,a是个常量字符串,其中a的变量名表示首元素的地址,开始pa-->w,后来pa++-->a,所以&s打印出''at''。

    下面正式进入我们的压轴大题,小伙伴们准备好接收挑战了吗? 

    笔试题 8

    1. int main()
    2. {
    3. char *c[] = {"ENTER","NEW","POINT","FIRST"};
    4. char**cp[] = {c+3,c+2,c+1,c};
    5. char***cpp = cp;
    6. printf("%s\n", **++cpp);
    7. printf("%s\n", *--*++cpp+3);
    8. printf("%s\n", *cpp[-2]+3);
    9. printf("%s\n", cpp[-1][-1]+1);
    10. return 0;
    11. }

    最初的内存布局


     我们画出最初的内存布局后,就开始解题。

    1**ccp,从图中我们可以很明显的看出指向的是字符串FIRST(cpp-->c+2).

    2*--*++cpp+3(注意++--都是改变量的值),这里我们靠近变量的操作符先进行运算,++cpp,这使得cpp指向c+1,*(c+1)找到c+1,在--*++cpp指的是c+1-->c,*--*++cpp便找到字符串ENTER的首地址,然后,*--*++cpp+3,找到E的地址,打印ER。(cpp-->c+1,c+1-->c)。

    3*cpp[-2]+3-->*(cpp-2)+3,这里cpp-2使得cpp指向c+3,*(c+3)找到FIRST的首地址,*(cpp-2)+3找到S的首地址,打印ST。(cpp-->c+3)

    4cpp[-1][-1]+1-->*(*(cpp-1)-1)+1,cpp-1指向c+2,*(cp-1)-1-->(指向)c+1,*(*(cpp-1)-1)找到NEW的首地址,*(*(cpp-1)-1)+1找到E的地址,打印EW。

     总结

    1在做指针类型的题目的时会画图分析很重要。

    2p[1]可以等价于*(p+1),p[1][1]也可以等价于*(*(p+1)+1).

    3要牢记数组名就是首元素的地址(二种特殊情况就不多说了)。

    4指针-指针意义是表示二指针间的元素个数。


    大家喜欢的话就点个赞支持博主吧!

     

  • 相关阅读:
    弘辽科技:淘宝什么情况下需要提升销量?店铺怎么提升销量?
    java计算机毕业设计VUE技术小区车辆档案车位管理系统设计与实现源码+mysql数据库+系统+lw文档+部署
    洛谷 P1303:A*B Problem(高精度×高精度)
    JavaScript系列之构造函数与原型
    Ubuntu16.04 python matplotlib 输出轴标签出现中文乱码
    蛋白质宇宙
    文字转音频软件哪个好用?这3款文字转换音频的软件识别率很高
    顺丰同城前端一面
    卡奥斯低代码平台新版本体验活动
    分类预测 | MATLAB实现KOA-CNN-BiLSTM开普勒算法优化卷积双向长短期记忆神经网络数据分类预测
  • 原文地址:https://blog.csdn.net/qq_61552595/article/details/125609814