指针面试题详解

发布时间:2024年01月15日

指针笔试题解析

数组名是首元素地址,两种情况除外:
1.sizeof(数组名) , 这是这是计算整个数组的大小,单位是字节;
2.&数组名 , 得出的是整个数组的地址;

笔试题1
#include<stdio.h>
int main()
{
    int a[5] = { 1, 2, 3, 4, 5 };
    int* ptr = (int*)(&a + 1);
    printf("%d,%d", *(a + 1), *(ptr - 1)); //2  5
    //*(a+1),a是首元素地址,+1就是第二个元素的地址解引用就是2
    //&a+1跳过的是整个数组,指向的是整个数组后的地址
    //*(ptr-1),指向的是整个数组后的地址,-1则是数组的最后一个元素地址,解引用就是5
    return 0;
}

在这里插入图片描述

笔试题2
#include<stdio.h>

struct Test
{
    int Num;
    char* pcName;
    short sDate;
    char cha[2];
    short sBa[4];
}*p;
//假设p 的值为0x100000。 如下表表达式的值分别为多少?
//已知,结构体Test类型的变量大小是20个字节
int main()
{
    printf("%p\n", p + 0x1);
    //p的类型是struct Test,所以结构体指针p+1跳过的是整个结构体的大小(20),%p是以16进制打印的,结果是0x00100014
    printf("%p\n", (unsigned long)p + 0x1);
    //把p强制转换成(unsigned long),无符号长整型p+1就是0x00100001
    printf("%p\n", (unsigned int*)p + 0x1);
    //p被强制转换成(unsigned int*),p就是无符号整型指针,整型指针p+1就是跳过了4个字节,则结果是0x100004
    return 0;
}

笔试题3
int main()
{
    int a[4] = { 1, 2, 3, 4 };
    int *ptr1 = (int *)(&a + 1); 
    //&a是整个数组的地址,&a+1跳过整个数组
    int *ptr2 = (int *)((int)a + 1);
    printf("%x,%x", ptr1[-1], *ptr2); 4  0x020000
    //ptr[-1] -> (ptr-1),指针-1,后移4字节,指向第4个元素
    //a是首元素地址,地址强转为int类型,int(a)+1又强转为int*类型,结果是a向后+1字节,然后以十六进制打印一个int元素
    return 0;
}

在这里插入图片描述

笔试题4
#include <stdio.h>
int main()
{
    int a[3][2] = { (0, 1), (2, 3), (4, 5) };
    int *p;
    p = a[0]; //a[0][0]
    printf( "%d", p[0]); //1
     return 0;
}

逗号表达式的结果是最后一个表达式的值;
数组实际存的是:a[3][2] = {1,3,5};
a[0]代表第一行第一个元素的地址,p[0] -> *(p+0) -> *p, 此时p[0]就是1

笔试题5
int main()
{
    int a[5][5];
    //p的类型:int (*)[4]
    //a的类型:int (*)[5]
    int(*p)[4];
    p = a;
    printf( "%p,%d\n", 
    &p[4][2] - &a[4][2], //0xfffffc
    &p[4][2] - &a[4][2]); //-4
    //10000000 00000000 00000000 00000100  -4
    //11111111 11111111 11111111 11111011  
    //11111111 11111111 11111111 11111100 把这个值当成地址打印
    //0xfffffc
    return 0;
}

在这里插入图片描述

笔试题6
int main()
{
    int aa[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    int *ptr1 = (int *)(&aa + 1);
    //&aa是整个数组的地址,&aa+1跳过整个数组,ptr指向数组最后一个元素的后面
    int *ptr2 = (int *)(*(aa + 1));
    //aa是首元素地址,也就是aa[0]第一行的地址,aa+1,指向第二行的地址aa[1]
    printf( "%d,%d", *(ptr1 - 1), *(ptr2 - 1)); //10  5
    return 0;
}

在这里插入图片描述

笔试题7
#include <stdio.h>
int main()
{
     char *a[] = {"work","at","alibaba"};
     char**pa = a;
     pa++;
     printf("%s\n", *pa);
     return 0;
}

a是指针数组:存放char*类型的数组,数组有3个元素;
pa指向的是首元素地址,pa+1指向第二个元素at
在这里插入图片描述

笔试题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); //POINT
     //cpp最开始指向c+3,*(++cpp)指向下一个元素:c+2
     printf("%s\n", *--*++cpp+3); //ER
     //++优先级高于+,*(++cpp),cpp指向c+1,*__(c+1) -> *(c)+3 -> ER
     printf("%s\n", *cpp[-2]+3); //ST
     //*cpp[-1]+3 -> *(*cpp-2)+3 -> *(c+3)+3 -> ST
     printf("%s\n", cpp[-1][-1]+1); //EW
     //cpp[-1][-1]+1 -> *(*cpp-1)+1 -> *(c-1)+1 -> c[1]+1 -> EW
     return 0;
}

注意:++和–会改变指针本身的指向
在这里插入图片描述

总结

1.数组名是首元素地址,两种情况除外:
①sizeof(数组名) , 这是这是计算整个数组的大小,单位是字节;
②&数组名 , 得出的是整个数组的地址;

2.++和–会改变指针本身的指向;

文章来源:https://blog.csdn.net/weixin_65245159/article/details/135591413
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。