• 指针相关面试题目


    数组名的意义:
    1. sizeof( 数组名 ) ,这里的数组名表示整个数组,计算的是整个数组的大小。
    2. & 数组名,这里的数组名表示整个数组,取出的是整个数组的地址。
    3. 除此之外所有的数组名都表示首元素的地址。
    下面我们来看几道经典的面试题
    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. }

    我们首先要知道此处的(&a + 1)是什么——&a是取出整个数组的地址,原本ptr是指向1的地址,再给它+1就表示跳过这个数组,即

    (a+1)此处a表示首元素地址,+1表示第二个元素地址,所以*(a + 1)就是第二个元素,即2;

    *(ptr-1)就是指向5的地址,再解引用就是5;所以这道题答案是 2,5;

    2

    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. }
      int * ptr1 = ( int * )( & a + 1 );这里的 &a表示取出整个数组的地址,ptr1指向1的地址,+1跳过整个数组即指向4后面的地址,即
    ptr1[-1]等价于*(ptr1-1)即是指向4再解引用就是4;
      int * ptr2 = ( int * )(( int ) a + 1 );这里的a代表首元素地址,给其强制类型转化成int 再+1,即只跳过了int类型中的1个字节,整型在内存中是小端存储,即1,2,3,4原本在内存中应该是以0x00000001,0x00000002,0x00000003,0x00000004的形式存储,它们以小端存储即
    ,所以对ptr解引用*ptr=02000000,以%x的形式打印出来省去前面的0,结果应该是2000000;
    这道题答案是4,2000000;
    3
    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. }

    a是一个三行两列对的二维数组,注意此处对二维数组的初始化, int a[3][2] = { (0, 1), (2, 3), (4, 5) };,他们中间是用“ ,”隔开,不是“ {}”,所以,他只初始化了3个元素,即1,3,5,剩下的全是0,即这个二维数组应该是

     p = a[0];a[0]表示的是&a[0][0], p就指向1的地址,p[0]表示*(p+0)就是*p就是1;

    4

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

    a是int(*)[5]类型,p是int(*)[4]类型,如图所示

    & p [ 4 ][ 2 ] - & a [ 4 ][ 2 ],就是他们中间有几个元素,如图,结果是-4,分别以%p和%d形式打印,就是

    FFFFFFFC和-4

    5

    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. }
      int * ptr1 = ( int * )( & aa + 1 );&aa表示整个二维数组的地址,指向1,+1表示跳过整个数组,指向第10后面的地址,*(ptr1-1)就是指向10的位置解引用就是10;
    int * ptr2 = ( int * )( * ( aa + 1 ));aa表示二维数组首元素地址即是第一行的地址指向1,+1表示跳过第一行指向第二行首元素的地址6,*(ptr2-1)就是指向5的位置,解引用就是5.
    所以这道题答案是10,5
  • 相关阅读:
    014 - ARM64上的GIC-400(GICv2)
    100+Python挑战性编程练习系列 -- day 22
    安装Anaconda
    分享一个全新的轻量级JDBC读写分离(主备数据库访问)方案
    Selenium的WebDriver操作页面的超时或者元素重叠引起的ElementClickInterceptedException
    玩转nginx的配置文件2
    Java算法 每日一题(五) 编号209:长度最小的子数组
    adb 命令查看进程
    [LINUX使用] iptables && tcpdump && wireshark && tshark
    一起Talk Android吧(第三百六十二回:多线程之线程中断)
  • 原文地址:https://blog.csdn.net/weixin_67131528/article/details/134041792