• 指针笔试题讲解



    题目

    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
    //由于还没学习结构体,这里告知结构体的大小是20个字节
    //由于还没学习结构体,这里告知结构体的大小是20个字节
    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
    • 20
    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
    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
    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
    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
    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
    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

    答案与解析

    重点知识点:
    数组名在大多数情况下表示数组首元素的地址,但是两种情况除外
    (1)sizeof(数组名),这时表示整个数组的大小
    (2)&数组名,这时表示整个数组的地址

    1、

    答案:
    在这里插入图片描述

    解析:

    int main()
    {
        int a[5] = { 1, 2, 3, 4, 5 };
        int* ptr = (int*)(&a + 1);//&a,取出的是整个数组的地址,加一,跳过整个数组的大小
        printf("%d,%d", *(a + 1), *(ptr - 1));//这里两个都是int*类型的指针,且都是普通的加减一,都只跳过4个字节
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里插入图片描述

    2

    答案:

    解析:

    int main()
    {
        p = (struct Test*)0X100000;
        //这里的p是结构体指针,加一跳过一个结构体大小的字节,跳过20个字节,由于是16进制,所以显示14
        printf("%p\n", p + 0x1);
        //这里将p强制转化为了unsigned long类型,非指针,加一就只是加1个字节
        printf("%p\n", (unsigned long)p + 0x1);
        //这里将p强制转化为了unsigned int* 类型,加一跳过一个Int类型的大小,4个字节
        printf("%p\n", (unsigned int*)p + 0x1);
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    3

    答案:
    在这里插入图片描述

    解析:

    int main()
    {
        int a[4] = { 1, 2, 3, 4 };
        //&a 取出的是整个数组的地址,加1跳过整个数组的大小(4 * 5 =20个字节)
        int* ptr1 = (int*)(&a + 1);
        //将p转化为Int 类型,加一就只会跳过一个字节
        int* ptr2 = (int*)((int)a + 1);
        printf("%x,%x", ptr1[-1], *ptr2);
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在这里插入图片描述

    4、

    答案:
    在这里插入图片描述

    解析:

    int main()
    {
        //下面数组中的元素有逗号表达式:例:(0,1),这样只会取到1的值,所以数组元素是(1,3,5)
        int a[3][2] = { (0, 1), (2, 3), (4, 5) };
        int* p;
        //a[0]是二维数组第一行的数组名,其内有1,3 两个元素
        p = a[0];
        //p[0] = 1
        printf("%d", p[0]);
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    5、

    答案:
    在这里插入图片描述

    解析:

    int main()
    {
        int a[5][5];
        //数组指针类型
        int(*p)[4];
        //类型不一样,但是也可以存储,只是每次存储4个值
        p = a;
        //&p[4][2]-&a[4][2] = -4;将地址转化为16进制
        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
    • 9
    • 10
    • 11

    在这里插入图片描述

    6、

    答案:
    在这里插入图片描述

    解析:

    int main()
    {
        int aa[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
        //&aa 是取整个数组的地址,加1跳过整个数组
        int* ptr1 = (int*)(&aa + 1);
        //aa 代表二维数组第一行的值,加1跳过5个元素
        int* ptr2 = (int*)(*(aa + 1));
        printf("%d,%d", *(ptr1 - 1), *(ptr2 - 1));
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    7、

    答案:
    在这里插入图片描述

    解析:

    int main()
    {
    	//是一个指针数组,存储的是美格字符串的首元素一直
    	char* a[] = { "work","at","alibaba" };
    	//二级指针来保存a的地址
    	char** pa = a;
    	//正常的加1,跳过一个元素
    	pa++;
    	printf("%s\n", *pa);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    8、

    答案:
    在这里插入图片描述

    解析:
    解析:

    1. c[]中存放的数据是每个字符串的首元素
    2. cp[]中存放的数据其实就是c中的反过来
    3. 对1:++cpp执行,指向c+2,解引用,得到c+2,再解引用得到了P的地址,打印出point
    4. 加号的优先级很低,先算其他的;打印的时候会把获得地址到\0之间的地址都打印
    5. 对2:++cpp执行,指向c+1,解应用得到C+1,指向N,–执行,指向E,解引用,得到E的地址,在加3,向后移3未,得到的是ENETR中第二个E的地址
    6. cpp已经经过了两次++,cpp[-2]得到得是跳转到C+3,得到F的地址,在进行解引用,跳到FIRST地址中,+3得到S的地址
    7. 对4:cpp还是指向c+1,cpp[-1]跳转到C+2,指向P,cpp[-1][-1]跳转到P的上一个NEW中,对其+1,得到E的地址
      在这里插入图片描述
  • 相关阅读:
    gRPC之拦截器与元数据
    JavaScript进阶(二十九): 走近 es6 之 new.target
    Answering the SDIs Step by Step
    Redis分布式锁Redisson
    第三天:java基础复习(3)
    前端技能树,面试复习第 52 天—— 手写代码:Javascript 基础考核
    OpenCV--图像的运算
    短时间内防止多次点击
    【OpenWrt】N1刷机过程及旁路由设置(通用)
    Java.lang.Class类 getField(name)方法有什么功能呢?
  • 原文地址:https://blog.csdn.net/wjfwonderful/article/details/133219284