• 指针笔试题(帮助你全面理解指针!!!)


    目录

    笔试题1:

    笔试题2:

    笔试题3:

    笔试题4:

    笔试题5:

    笔试题6:

    笔试题7:


     

    笔试题1:

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

    程序的结果是什么呢?

    首先我们来运行一下程序:

    e2c71220d4f74b1681d40a9b113adb20.png

    则答案为    2     5

    详细分析:

    cccc74457a7644b2be7cb7e5e125f4f5.png

    &a-------int(*)[5](类型),如果要将&a赋值给p,则有int (*p)[5] = &a

    &a是数组的地址,&a+1跳过整个数组

    &a+1强制类型转换为和指针变量ptr相同的类型,ptr-1表示减去一个整型的地址

    *(a+1)a是数组名,表示首元素地址,a的类型为(int*),如图a位置,加1表示跳过一个元素,指向2的位置,如图a+1解引用后值为2。

    笔试题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 的值为0x100000。 如下表表达式的值分别为多少?
    10. //已知,结构体Test类型的变量大小是20个字节
    11. int main()
    12. {
    13. p = (struct Test*)0x100000;
    14. printf("%p\n", p + 0x1);
    15. printf("%p\n", (unsigned long)p + 0x1);
    16. printf("%p\n", (unsigned int*)p + 0x1);
    17. return 0;
    18. }

    程序的结果是什么呢?

    运行代码:

    edb0a94f9cc44631b26ce2ba13475fc7.png

     则答案为    00100014    00100001    00100004

    详细分析:

    p+0x1:表示p+1,指针加1(取决于指针类型——结构体指针),此结构体类型的大小为20个字节,所以增加20,而地址的表示方法是16进制,20的16进制为14,最终结果为00100014。

    (unsigned long)p+0x1:p是一个结构体指针类型,将结构体指针类型强制类型转换为unsigned long类型,整形加1就是加1,结果为00100001。

    (unsigned int*)p+0x1:将结构体指针类型强制类型转换为unsigned int*类型,整形指针+1,跳过4个字节,最终结果为00100014。

    笔试题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. }

    程序的结果是什么呢?

    运行代码:

    cc62150644c54948bd4870a92957400c.png

    则答案为    4    2000000

    详细分析:

    b0e529900320418c99286e0b6ea5d485.png

    %p --------- 是打印地址

    %x --------- 是16进制的格式打印

    &a+1:增加一个数组a的大小;将其转化为int*类型在赋给指针变量ptr1。如图所示

    (int)a + 1:a是一个数组名,表示首元素地址,首元素的地址强制类型转换为整形,整形加一就是加一,跳过一个字节;将其转化为int*类型在赋给指针变量ptr2。

    ptr1[-1] ------->  *(ptr1-1)

    ptr1为一个整型指针,整形指针减一,即向前移一个整型,如图所示 ptr1-1,解引用向后访问四个字节(04  00  00  00),即为4

    ptr2为一个整型指针,解引用向后访问4个字节,如图所示(00  00  00  02),假设是小端放入,还原回来就是(02  00  00  00),16进制打印出来就是0x2000000

    笔试题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. }

    程序的结果是什么呢?

    运行代码:

    d374ca6c3625447694c808a52add3094.png

    则答案为    1

    详细分析:

    5cb86deeabba4b62847e1b0760735140.png

    区别于:int a[3][2] = { {0, 1}, {2, 3}, {4, 5} };

    原题为逗号隔开的表达式,表达式结果为:int a[3][2] = { 1, 3, 5 };

    a[0]:第一行的数组名,没有单独放入sizeof内部,数组名表示首元素地址。相当于&a[0][0]

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

    程序的结果是什么呢?

    运行代码:

    2c19ef50b9bd4644aa234ac4658c3b74.png

    则答案为    FFFFFFFC   -4

    详细分析:

    4cc7d41dfcc84b9bbd7ab649e0301208.png

    int (*p)[4]:p为一个指针,指向一个数组,是四个元素,每个元素是整形

    把a赋值给p,a是一个数组名(表示首元素的地址),即二维数组的第一行地址

    a--------->int (*)[5]类型      p------->int (*)[4]类型

    p+1:跳过4个整形

    p[4][2] ----------->  *(*(p+4)+2):对于p+4(数组指针)解引用有权利会访问到4个整形元素

    &p[4][2] - &a[4][2]:指针和指针相减得到的是指针之间的元素个数,小地址减大地址(负数),得到-4,

    -4:以%d打印就是 -4,以%p(地址)打印就是 FFFFFFFC 如图所示(内存以补码的形式存储)

    笔试题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. }

    程序的结果是什么呢?

    运行代码:

    b1a7dad71fe54a4a86b0518f6722c3d7.png

     

    则答案为    10    5

    详细分析:

    40d139672af9489fa745ced28cf6adc3.png

    二维数组的本质是一维数组,比如此题的数组aa表示数组内含有两个元素,分别是两个一位数组,

    而这两个一维数组又分别包含五个元素。

    &aa+1:aa表示整个数组的地址,加1为跳过整个数组。

    *(aa+1):aa为数组首元素的地址(第一行的地址),加1(第二行地址),解引用得到第二行(*(aa+1) ---------> aa[1]----第二行的数组名没有单独放入sizeof内部,也没有取地址,表示首元素地址,即&aa[1][0])

     ptr1和ptr2都为指针,指针减整型,减去存储内存的元素的类型。

    ptr1-1:向前移动一个整型指针,解引用得到10

    ptr2-1:向前移动一个整型指针,解引用得到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. }

    程序的结果是什么呢?

    运行代码:

    25b73c3e36864fceb23d022a5e9d3b3c.png

    则答案为    at

    详细分析:

    f2920b58470947a9b5bb5313b5896933.png

    char* a[]为指针数组,是数组用来存放指针,该数组有三个元素,分别是三个字符串的地址。

    pa = a:是将数组a的首元素的地址放入二级指针变量pa中。

    pa++:跳过一个char*的元素

    *pa:此时pa为a[1],也就是第二个元素表示字符串的首地址,以%s的形式输出,依次打印字符串。

     

     

     

     

  • 相关阅读:
    【大模型和智能问答系统】
    数字IC笔试千题解--逻辑推理篇(七)
    RabbitMQ如何实现延迟消息?
    渗透工具-白帽安全工程师Kali linux系统
    APM Profile 在系统可观测体系中的应用
    前端入门学习笔记四十六
    黑马瑞吉外卖之套餐信息的删除
    【Java】数组
    kwebio/kweb-core:面向后端的轻量级 Kotlin Web 框架
    Android——共享参数SharedPreferences
  • 原文地址:https://blog.csdn.net/m0_72161237/article/details/126764338