• 大厂经典指针笔试题


    本部分为指针经典题,努力练习,拒绝一看就会,一写就fei


    🚀目录:

    指针经典题

    1.本题为经典指针笔试题的集大成者

    2.画图、画图、画图

    3.经典题:


    🔥🔥🔥经典题:

    🌵笔试题1:

     🔺特别注意:

    int* ptr = (int*)(&a + 1);

    //&a取出的是整个数组的地址,因此&a的类型是int(*)[5],该类型+-1跳过的是5个int型

    //强制类型转换,类型发生变化,而值不变

    printf("%d,%d", *(a + 1), *(ptr - 1));

    //*(ptr-1)为什么只跳过1个int型,因为ptr的类型是int*,该类型+-1跳过1个int型

    若int* p=&a;*说明p是指针变量,int说明p指向的对象是int类型。p的类型是int*

    🔸本题答案:2,5

    🔸代码如下:

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

    🌵笔试题2:

    🔺特别注意:

    这里的0x1是十六进制,转换成十进制为1

    已知p的值是0x100000,

    printf("%p\n", p + 0x1);

    //p是一个结构体类型指针变量,p+-1代表着跳过一个结构体类型大小

    若p是一个整型指针变量,p+-1代表着跳过一个整型大小

    printf("%p\n", (unsigned long)p + 0x1);

    (unsigned long)p,p的类型发生变化但值不变,

    p的值是0x100000,转换成unsigned int类型后为1048576,+1为1048577,该值的地址就是0x100001

    printf("%p\n", (unsigned int*)p + 0x1);
    //若p是一个整型指针,p+-1代表着跳过一个无符号整型大小

    🔸本题答案:

        0x100014,0x100001,0x100004

    🔸代码如下:

    1. #include <stdio.h>
    2. struct Test
    3. {
    4. int Num;
    5. char* pcName;
    6. short sDate;
    7. char cha[2];
    8. short sBa[4];
    9. }*p;
    10. int main()
    11. {
    12. printf("%p\n", p + 0x1);
    13. printf("%p\n", (unsigned long)p + 0x1);
    14. printf("%p\n", (unsigned int*)p + 0x1);
    15. return 0;
    16. }

    🌵笔试题3:

    🔺特别注意:

    int* ptr2 = (int*)((int)a + 1);

    //a是数组首元素的地址,强制类型转换成int型,值不变,类型发生变化

    //若a=0x0012ff40,则a+1=0x0012ff44,(int)a+1=0x0012ff41

    该数组在内存中的存储,vs采用小端存储模式,0x00 00 00 01在内存中存储为01 00 00 00

    printf("%x,%x", ptr1[-1], *ptr2);

    //ptr2的类型是int*,解引用操作访问1个整型大小,再按十六进制打印

    🔸本题答案:4,2000000

    🔸代码如下:

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

    🌵笔试题4:

    🔺 特别注意:

    int a[3][2] = { (0,1),(2,3),(4,5) };

    //这里是逗号表达式,注意是(),不是 { } ,看下图体会区别!

    🔸本题答案:1

    🔸代码如下:

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

    🌵笔试题5:

    🔺 特别注意:

    int a[5][5];

    //在二维数组int a[5][5]中,a为数组首元素的地址,类型为int (*)[5];

    int(*p)[4];

    //p指向的数组有4个元素,每个为int型,+1跳过1个(4个int类型的数组)

    p = a;

       int (*)[4]=int (*)[5];

       printf("%p\n", &p[4][2] - &a[4][2]);
    //&p[4][2]和&*(*(p+4)+2)一样。p是个数组指针,+4跳过4个(4个int类型的数组)

    //p++为上图绿色图标,橙色为p[4]解引用

    &p[4][2] - &a[4][2]=-4;

    //-4按%p打印,是将-4的补码转换成十六进制

    原码:

    10000000 00000000 00000000 00000100

    反码:

    11111111 11111111 11111111 11111011

    补码:

    11111111 11111111 11111111 11111100

    得到 0xFF FF FF FC

    🔸本题答案:FF FF FF FC,-4

    🔸代码如下:

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

    🌵笔试题6:

    🔺特别注意:

    int* ptr1 = (int*)(&aa + 1);

    //&aa得到的是整个数组的地址,+1跳过整个二维数组

    int* ptr2 = (int*)(*(aa + 1));

    //aa为二维数组第一行的地址,

    *(aa + 1)=aa[1],aa[1]为第二行首元素的地址,此类型为int*,因此这里的(int*)多余

    🔸本题答案:10,5

    🔸代码如下:

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

    🌵笔试题7:

    🔺 特别注意:

    char* a[ ] = { "work","at","alibaba" };

    //该数组存的是work、at、alibaba首元素的地址

    char** pa = a;

    //pa指向的是a数组第二个元素,解引用后得到at首元素的地址

    printf("%s\n", *pa);

    //printf打印时,%s会根据首元素的地址,向后打印,遇到\0停止

    🔸本题答案:at

    🔸代码如下:

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

    🔥🔥🔥笔试题8:

    本题为指针笔试题的集大成者

    🔺特别注意:

    代码剖析:

    ++cpp后cpp指向的地址会发生变化

    printf("%s\n", **++cpp);

    //++cpp后,cpp指向c+2,第一次解引用后得到c+2,而c+2指向数组c第三个元素,第二次解引用后得到数组c第三个元素“POINT”首字符的地址,printf打印时,%s根据首字符P的地址向后打印,遇到\0停止

    printf("%s\n", *--*++cpp+3);

    //++cpp后,cpp指向c+1,第一次解引用后得到c+1,c+1再-1指向数组c第一个元素,第二次解引用后得到数组c第一个元素"ENTER"首字符的地址,+3得到T的地址,printf打印时,%s根据字符T的地址向后打印,遇到\0停止

    printf("%s\n", *cpp[-2]+3);

    //**(cpp-2)+3;cpp-2指向c+3,第一次解引用后得到c+3,该地址指向数组c第四个元素,第二次解引用后得到数组c第四个元素"FIRST"首字符的地址,+3得到R的地址,printf打印时,%s根据字符R的地址向后打印,遇到\0停止

    printf("%s\n", cpp[-1][-1]+1);

    //cpp[-1][-1]+1和*(*(cpp-1)-1)+1;cpp-1指向c+2,第一次解引用后得到c+2,该地址-1指向数组c第二个元素,第二次解引用后得到数组c第二个元素"NEW"首字符的地址,+1得到E的地址,printf打印时,%s根据字符E的地址向后打印,遇到\0停止

    🔸本题答案:POINT,ER,ST,EW

    🔸代码如下:

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

    🚀结语:

    如果对您有帮助的话,

    不要忘记点赞+关注哦,蟹蟹

    如果对您有帮助的话,

    不要忘记点赞+关注哦,蟹蟹

    如果对您有帮助的话,

    不要忘记点赞+关注哦,蟹蟹

  • 相关阅读:
    【微服务|OpenFeign】OpenFeign快速入门|基于Feign的服务调用
    【鸿蒙软件开发】ArkTS基础组件之Rating(评分组件)、RichText(富文本显示)
    【JavaEE初阶】多线程 _ 基础篇 _ 线程池(案例四)
    软件过程与管理学习之(1)Project management Methodologies & Standards(项目管理方法和标准)
    Java递归算法
    rk3588对npu的再探索,yolov5使用rknn模型推理教程
    详解win11系统的硬件最低配置要求
    Linux常用命令学习3
    【人工智能】基于八数码问题对比搜索算法的性能
    【信息安全】-虚拟专用网络
  • 原文地址:https://blog.csdn.net/qq_68993495/article/details/125589702