• 赶紧进来看看!!!你一定要会做的八道经典指针笔试题!!!


    本文详细介绍了八大指针经典笔试题,内涵盖指针大部分的用法,
    全部了解掌握其原理之后对指针的学习大有帮助!!!
    对指针掌握 也就掌握了内存,C语言也就没有什么更绕的了

    在这里插入图片描述

    一.八道经典指针笔试题and解析

    以下题目均在32位平台下小端存储 测试运算结果

    1.指针笔试题一(题目)

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

    ①.指针笔试题一(答案+文字解析)

    答案:2,5
    解析: (&a+1)先算&a ,而&数组名,数组名表示整个数组,&a+1为一维数组指针+1移动一个步长,步长大小为数组大小个字节即20个字节
    得到的是整个数组后面的一块同类型大小的数组地址(以第一个内存单元的地址作为代表整个数组地址),将其强制类型转换为int *(即这个第一个内存单元的地址类型转换为整形指针代表着一个整形的地址)整形指针存放在ptr整形指针变量里

    而*(a+1),a为数组名,这里表示首元素地址即存放1的整形空间地址,+1后移动四个字节大小,得到第二个元素地址,即存放2的空间地址,解引用后得到存放2的空间,输出结果为2

    *(ptr-1)里ptr为指针变量,存放的是整个数组后面的即第五个元素后面的一个整形空间的地址,减1即往前移动一个步长大小为4个字节得到的是存放5的空间地址,解引用后得到了存放5的空间,输出结果为5

    ②.指针笔试题一(运行结果+图解)

    在这里插入图片描述
    在这里插入图片描述

    ③,指针笔试题一(细节总结)

    1.要区分&a+1 和a+1的区别
    2.&a+1跨越整个数组字节的一个数组指针,a+1为数组第二个元素的指针
    3.地址是什么类型决定着解引用访问多大空间决定着加减整数移动的步长大小是多大,
    4.指针本身是什么类型最后要看赋进去的变量是什么类型,要强转类型转换什么类型,

    2.指针笔试题二(题目)

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

    ②.指针笔试题二(答案+文字解析)

    答案:00100014
    00100001
    00100004

    解析:p为struct Test 类型的指针变量,存放的0x100000强制类型转换为结构体指针类型的数据,即p里面就是为00100000(地址默认是以十六进制形式表示的不需要0x)

    p+0x1 ,0x1是十六进制的1,转换为十进制还是为1
    p+1 即指针加1 移动一个步长,步长大小为结构体变量大小即20个字节
    即00100000+20,又因为地址序列是十六进制 所以要逢十六进1,
    结果为00100014,以地址形式打印出来即为该结果

    (unsigned long)p 表示将p里的指针强制类型转换为无符号长整形类型
    在当前平台 其类型为4个字节,而p里面是地址00100000 转换为无符号长整形 十六进制形式就是0x100000 然后+0x1 结果为十六进制0x100001
    以地址形式打印出这串序列 结果就是00100001

    (unsigned int *)p表示将00100000强制类型转换为无符号整形指针类型,而这个整形指针p+0x1即表示移动一个步长,而步长大小就是4个字节
    则结果为00100004,以地址形式打印出来结果为00100004

    ②指针笔试题二(运行结果+图解)

    在这里插入图片描述
    在这里插入图片描述

    ③指针笔试题二(细节总结)

    1.地址默认在计算机里是用十六进制形式表示,并且取决于计算机运算平台,32位则是8个十六进制,64位则是16个十六进制数,不用0x前缀
    2.0x前缀的数字表示是十六进制数字,强制转换为指针后作为的是地址而不是数字 0x要去掉,不足地址位的要补0
    3.指针加减的步长多大取决于类型,步长是十进制整数,地址是十六进制加的字节超过15则会进1
    4.以十六进制形式打印地址 左边多余的0会省略输出形式是%#x时会输出的时候前面加0x,以地址形式打印十六进制,左边不足8位的会补0表示地址

    3.指针笔试题三(题目)

    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    ①指针笔试题三(解析)

    答案:4,2000000
    解析:(int*)(&a+1)得到的是整个整形数组指针加1 地址加整个数组字节
    得到这个数组后的一个数组指针,再将这个指针强转为整形指针类型

    (int*)((int)a+1) 为将a即数组首元素地址强制类型转换为整形,假设这个指针为00 12 00 00,转换为整形就是十六进制的数字0x12 00 00 加1得到的是0x12 00 01 ,又将其转换为整形指针得到的是00 12 00 01
    与原来首元素的指针相比是增加了一个字节
    则是当前这个整形指针表示是数组第一个整形空间的第二个内存单元的地址做代表

    ptr1[-1]等价于 *(ptr-1),ptr是当前数组后面的一个整形指针,减1移动一个步长4个字节 得到的是数组第四个元素的地址,解引用得到的结果为4
    以十六进制形式输出为4

    *ptr2 表示解引用访问当前指针指向的整形空间,即当前指针指向的内存单元加上后面的三个内存单元的空间,而ptr2是第一个整形空间内第二个内存单元的地址
    因为数组的内存单元地址是连续的访问的是第一个整形空间后三个内存单元和第二个整形空间第一个内存单元 里面值为00 00 00 02
    按小端形式取出来为02 00 00 00,以十六进制形式打印这串数字得到2000000

    ②指针笔试题三(运行结果+图解)

    在这里插入图片描述
    在这里插入图片描述

    ③指针笔试题三(细节总结)

    1.分清楚&a和a的区别
    2. 数组内部存放数据的内存单元是连续的
    3. 访问内存单元的数据要按存储时大小端方式将数据取出来重新排列->大小端存储

    4.指针笔试题四(题目)

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

    ①.指针笔试题四(答案+文字解析)

    答案:1
    解析:二维数组有三行二列,数组里的是逗号表达式(结果为最后一个表达式的值)实际上第一行第一和二列放的是 1 和3 第二行第一列放的是5 未完全初始化其他都放的是0

    a[0]等价于*(a+0)即数组首元素地址解引用 ,二维数组首元素的第一行,即最后得到的是数组第一行,=而数组第一行又等价于第一行数组名即数组第一行首元素地址,即1的地址

    p里面存放的是数组第一行第一列的整形空间起始地址,p[0]仍然表示将这个指针解引用得到的是第一行第一列的元素 1

    ②.指针笔试题四(运行结果+图解)

    在这里插入图片描述
    在这里插入图片描述

    ③.指针笔试题四(细节总结)

    1.要注意逗号表达式结果是最后一个表达式的结果->逗号表达式
    2.二维数组名为首元素地址
    3.数组未完全初始化 ,其他部分默认为0
    4a[0]等价于
    (a+0)
    *

    5.指针笔试题五(题目)

    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    ①.指针笔试题五(答案+文字解析)

    答案:FFFFFFFC,-4
    解析:a为一个五行五列的二维数组数组名,p是一个四个元素的整形数组指针变量
    将a存在p里,是根据p的类型来决定存放的a是什么类型的,a本身是数组名是第一行数组指针为指向五个整形元素的数组指针.
    但是a会转换为指向四个元素的整形数组指针变量放在p里,
    p此刻存放的是指向a这个二维数组第一行前四列的元素的指针

    &p[4][2] 表示的是第五行第三个元素,而每行是4个元素,将a这个二维数组五行五列排列成连续的一段一维数组实际上是25五个整形元素组成
    而&p[4][2]指的是第19个整形元素的地址,
    &a[4][2]得到的是二维数组第五行第二个元素即第
    指向的是第23个元素的地址

    &p[4][2]-&a[4][2]等价于-(&a[4][2]-&p[4][2])
    而指针相减得到的是两个指针间的元素个数即为4结果为-4
    而以地址形式输出-4输出的是-4的在计算机内的补码即11111111111111111111111111111100 转换为十六进制是FFFFFFFC
    而以整数形式输出-4 结果为十进制原码 -4

    ②.指针笔试题五(运行结果+图解)

    在这里插入图片描述
    在这里插入图片描述

    ③.指针笔试题五(细节总结)

    1.p=a这里a和p都是一维数组类型 但是 a是指向五个元素的,p指向4个元素的,但是p是变量,a最后会类型转换为指向4个元素的指针赋给p
    2.指针相减是高地址指针减低地址指针且是同一个数组里的,得到的是两个指针间的元素个数
    3. 地址是指计算机内部的数字补码才会作为地址,而我们得到的使用的数字是又补码转换为的原码,一个原码变为地址要转换为补码然后再对应其地址

    6.指针笔试题六(题目)

    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    ①指针笔试题六(答案+文字解析)

    答案:10,5
    解析:(int*)(&aa+1),&aa,aa是数组名表示整个,&aa表示的是取整个二维数组的地址,然后加1移动一个步长,步长大小为整个二维数组的大小个字节,即地址跨越整个数组,指向二维数组后面的一个二维数组大小的地址,将其强转为int *表示这个指针类型转为整形指针了,指向整形空间的指针赋给ptr1

    (int *)( * (aa+1))中先算aa+1 ,aa数组名这里表示首元素地址,为数组第一行地址,+1移动一个步长 大小为数组第一行大小个字节,结果为数组第一行后面的一行数组地址即数组第二行指针,解引用得到数组第二行,数组第二行又等价为数组第二行数组名 为数组第二行第一个元素地址,本身就是整形指针,将其转换为整形指针没有变化,赋值给ptr2

    *(ptr1-1),ptr1为整个二维数组后面一个整形空间的地址,-1移动四个字节为二维数组最后一个元素的地址 解引用得到最后一个元素结果为10

    *(ptr2-1) ptr2为数组第二行第一个元素地址,-1 移动4个字节 为数组第一行最后一个元素地址 ,解引用得到了5

    ②指针笔试题六(运行结果+图解)

    在这里插入图片描述
    在这里插入图片描述

    ③指针笔试题六(细节总结)

    1.区分&aa 取整个数组地址和aa首元素地址
    2.二维数组数组名表示第一行地址
    3.二维数组某一行 是等价于该行数组名即该行首元素地址

    7.指针笔试题七(题目)

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

    ①.指针笔试题七(答案+文字解析)

    答案:at
    解析:a是一个字符指针数组名,表示首元素地址即一个二级字符指针
    而字符指针数组每个元素都是一个字符指针空间,而常量字符串存放在字符指针空间是把字符串首字符地址即字符指针存放在空间里

    a数组名即 指向第一个字符指针元素的地址给pa
    pa++ 结果为指向数组第二个元素的地址即指向指向字符串at第一个字符a的地址

    *pa 解引用得到指向字符串at第一个字符a的地址,通过%s字符串格式输出得到字符串at

    ②.指针笔试题七(运行结果+图解)

    在这里插入图片描述
    在这里插入图片描述

    ③.指针笔试题七(细节总结)

    1.字符指针变量存放常量字符串时存的是字符串第一个字符地址
    2.%s输出字符串 输出项只需要字符串第一个字符地址
    3.常量字符串实际在内存的常量区开辟的多个连续的存放字符空间存放的字符串每个字符,表现形式是这些存放字符串的空间第一个字符的地址

    8.指针笔试题八(题目)

    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    ①.指针笔试题八(答案+文字解析)

    答案:POINT
    ER
    ST
    EW

    解析:c是一个字符指针数组有四个元素,存着的是这些字符串首字符地址
    cp是二级指针数组存的是c数组里每个字符指针的地址
    c+3是c数组第四个元素地址c+2是第三个c+1是第二个,c是第一个
    cpp是三级指针存的是cp数组名即首元素 地址 c+3的地址

    **++cpp 三个单目运算符优先相同结合性从右往左 先算++cpp表示cpp自加1再使用是指向c+2的指针 解引用为c+2即指向c数组第三个元素的指针 解引用用c数组第三个元素 即指向POINT中P的地址,输出字符串为POINT

    *- - *++cpp+3 根据运算符优先级和结合性先算++cpp 通过上一个语句cpp是指向c+2的 ++后为指向c+1的然后解引用为c+1是指向c数组第二个元素的地址 再–为指向C数组第一个元素的地址再解引用为 C数组第一个元素即存放ENTER 中E的地址 再加3 为指向第四个字符地址即E的地址 输出字符结果为ER

    *cpp[-2]+3 先算cpp[-2]等价于 *(cpp-2),而通过上题cpp为指向c+1的指针 -2后为指向c+3的指针解引用为c+3即指向C数组第四个元素的指针解引用为C数组第四个元素即指向FIRST中第一个字符F +3为指向第四个字符的地址即S的地址 输出字符串为ST

    cpp[-1][-1]+1 先*(cpp-1)为c+2 指向C数组第三个元素即然后再 -1 W为指向C数组第二个元素的指针解引用为C数组第二个元素 即指向NEW中N的地址 最后+1得到指向E的地址 输出字符串 结果为EW

    ②.指针笔试题八(运行结果+图解)

    在这里插入图片描述
    在这里插入图片描述

    ③指针笔试题八(细节总结)

    1.字符指针变量存放常量字符串存的是字符串首字符的地址
    2.%s输出字符串 输出项是字符地址表示从当前地址指向的字符开始往后输出字符串直到输出到\0结束
    3.运算顺序相同要看结合性
    4.–c自增会改变变量c里的值 c-1不会改变c里的值

    在这里插入图片描述

    二.总结

    本文详细介绍了八道经典指针笔试题,涵盖了指针大部分用法,全部理解了对指针有更深层次认识,熟悉了指针,也就对内存有了大概的认识
    至此对指针的了解 已经更进一层了…

    在这里插入图片描述

    写文不易,给个一键三连 支持下叭~~~

  • 相关阅读:
    微信小程序案例:2-2本地生活
    Web前端:React对比Vue,哪一个最适合开发人员?
    Docker安装Yapi
    Pthread 并发编程(二)——自底向上深入理解线程
    深度解析自然语言处理之篇章分析
    一文搞懂nginx的反向代理 负载均衡
    如何卸载 think-cell?丨卸载教程丨卸载办法
    LabVIEW+OpenVINO在CPU上部署新冠肺炎检测模型实战
    P2014 [CTSC1997] 选课(树形DP)
    XSS初级漏洞靶场
  • 原文地址:https://blog.csdn.net/lch1552493370/article/details/126830296