• 指针笔试题(带解析版)


    题目7——指针数组
     

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

    解析:

    题目6——二维数组

    1. int main()
    2. {
    3. int aa[2][5] = { 1,2,3,4,5,6,7,8,9,10 };
    4. //12345 678910
    5. int* ptr1 = (int*)(&aa + 1);
    6. //&aa + 1:指向10右边一位的地址
    7. int* ptr2 = (int*)(*aa + 1);
    8. //*aa + 1:首元素地址解引用+1=第一行第二个元素
    9. int* ptr3 = (int*)(*(aa + 1));
    10. //aa + 1:首元素地址+1
    11. //*(aa + 1)=*aa[1]=下一行元素
    12. printf("%d,%d,%d\n", *(ptr1 - 1), *(ptr2 - 1), *(ptr3 - 1));
    13. //*(ptr1-1)=ptr1[-1]=10
    14. //ptr2 - 1:指向第二个元素的指针-1再解引用=首元素=1
    15. // *(ptr3 - 1)=ptr3[-1]=指向元素6的指针向左移动一位=5
    16. return 0;
    17. }

    题目5——逗号表达式

    1. int main()
    2. {
    3. int a[3][2] = { (0,1),(2,3),(4,5) };
    4. //逗号表达式!!!
    5. //10 30 50
    6. int* p = a[0];
    7. //a[0]:首行第一个元素
    8. printf("%d\n", p[0]);
    9. return 0;
    10. }



    题目4——指针+1:

    1. struct MyStruct
    2. {
    3. int num;
    4. char* pcname;
    5. short sdate;
    6. char cha[2];
    7. short sba[4];
    8. }*p;
    9. //结构体大小为32字节
    10. //p=0x100000
    11. int main()
    12. {
    13. p = 0x100000;
    14. printf("%p\n", p + 0x1);
    15. //p:结构体指针,+1=下一个结构体指针,所以 p + 1 的地址比 p 高32字节
    16. //p+1=p+结构体大小=p+32(10进制)=0010 0000+0000 0020=0010 0020
    17. printf("%p\n", (unsigned long)p + 0x1);
    18. //0x10 0000(16进制)=1048576(10进制)
    19. //加1会增加地址的值,而不是指向下一个结构体
    20. //1048576+0x1(16进制)=1048576+1(10进制)=1048577=0010 0001(16进制)
    21. printf("%p\n", (unsigned int*)p + 0x1);
    22. //unsigned int*:整型指针类型,指针+1=下一个指针
    23. // 尽管平台是64位的,但是 unsigned int 的大小在几乎所有平台上都是4字节(32位),而不是8字节(64位)
    24. //p+1=p+4(64平台)=0010 0000+4(16进制)=0010 0000+8(10进制)=0010 0004
    25. return 0;
    26. }

    题目3——指针相减:
     

    1. int main()
    2. {
    3. int a[5][5];
    4. // 00000 00000 00000 00000 00000
    5. // a[0] a[1] a[2] a[3] a[4]
    6. int(*p)[4];
    7. //p:{0}{0}{0}{0}
    8. p = a;
    9. // 0000 0 000 00 00 000 0 0000 00000
    10. // p[0] p[1] p[2] p[3]
    11. printf("%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);
    12. // a[0] a[1] a[2] a[3] a[4]
    13. // 0000 0 000 00 00 000 0 0000 00000
    14. // p[0] p[1] p[2] p[3] p[4]
    15. //指针相减=两个指针之间的元素个数=-4
    16. // 原码 1000 0100
    17. // 反码 1111 1011
    18. // 补码 1111 1100
    19. //十六进制 fc
    20. return 0;
    21. }

    解析:

    题目2——指针在内存中所指的地址:

    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——指针在内存中所指的地址:

    1. int main()
    2. {
    3. int a[4] = { 1,2,3,4 };
    4. int* ptr1 = (int*)(&a + 1);
    5. //&a + 1:指向元素4右边的地址
    6. //(int*)(&a + 1):强制转换为int*类型
    7. int* ptr2 = (int*)((int)a + 1);
    8. //(int)a:数组首元素
    9. printf("%x,%x\n", ptr1[-1], *ptr2);
    10. //ptr1[-1]=*(ptr1+(-1))=*(ptr1-1)=指向元素4右边的地址向左边移动一位=4
    11. return 0;
    12. }


    解析:

  • 相关阅读:
    redis活跃非活跃连接数统计及client list说明
    C++类的六个默认成员函数(总结)
    【设计模式】二、UML 类图与面向对象设计原则 之 UML概述
    [附源码]计算机毕业设计springboot基于Vuejs的中国名茶销售平台
    软考中级和高级,有什么区别?
    联邦学习的梯度重构
    数据结构与算法(C语言版)P6---队列
    Java 日志系列(三):日志使用示例及常见报错
    vue 克隆代码块
    Android学习笔记 1.2.3 Gradle的属性定义 && 1.2.4 增量式构建
  • 原文地址:https://blog.csdn.net/m0_62014223/article/details/133554515