• 复杂的指针面试题


    分享几道有大坑的指针面试题目,如果看会看懂相信对于指针会有更深的理解! 

    例题1:

    1. const char* c[] = { "ENTER", "NEW", "POINT", "FIRST" };
    2. const char** cp[] = { c + 3, c + 2, c + 1, c };
    3. const char*** cpp = cp;
    4. int main(void)
    5. {
    6. printf("%s\n", **++cpp);
    7. printf("%s\n", *-- * ++cpp + 3);
    8. printf("%s\n", *cpp[-2] + 3);
    9. printf("%s\n", cpp[-1][-1] + 1);
    10. return 0;
    11. }

    首先对于【**++cpp】:cpp指向cp数组的首地址,++cpp,向后移动,指向cp的第二个元素地址,取*号解引用*++cpp,指向第二个元素的内容c+2,它指向POINT的首元素地址&P,最后一次解引用**++cpp,找到里面的内容POINT

    对于【*-- * ++cpp + 3】:首先清楚*,++,+,的运算符优先级,对于*和++二者优先级相同,计算顺序是从右到左,对于*和++或--都比+或-的优先级高,对于+或-运算顺序为从左向右

    明白这个我们开始看这条语句,因为上一步cpp已经指向了c+2的位置,因此++cpp指向c+1的位置,*++cpp就是c+1指向&N,而接下来--*++cpp指向c,再次解引用*--*++cpp也就是指向其即它的首元素地址&E,而最后+3即从&E向后移动三个单位指向(&E为+0),即指向了下一个&E,打印输出后面字符ER

    对于【*cpp[-2] + 3】:cpp[ -2]转换成指针即*(cpp-2),即等价于**(cpp-2)+3,首先cpp-2在上一步基础上指向了cp的第一个元素地址c+3处,解引用*(cpp-2)指向了c+3,再次解引用**(cpp-2)指向c数组最后一个元素地址&F,最终**(cpp-2)+3,指向FIRST的S地址,打印输出ST

    对于【cpp[-1][-1] + 1】 :等价于*(*(cpp-1)-1)+1,首先cpp-1指向c+2处地址,解引用*(cpp-1)为c+2,指向&P处,*cpp(-1)-1指向了c数组的c+1处,解引用*(*(cpp-1)-1)指向N,最后+1取到了E,最终打印EW

    最终结果:

     例题2:部分讲解写在了注释

    1. int main()
    2. {
    3. const char* str[] = { "welcome","to","Fortemedia","Nanjing" };
    4. const char** p = str + 1;//p存储 "to"字符串地址的地址,即&str[1]
    5. str[0] = (*p++) + 2;//str[0]指向'\0';因为是后置++,p++后还是指向to首地址
    6. // 整个(*p++) + 2结束后p才后移一位,指向了下一个字符串Fortemedia
    7. //存储"Fortemedia"字符串地址的地址, 即p=&str[2]
    8. str[1] = *(p + 1);//p+1后 p+1 = &str[3]; 则 str[1] = str[3] ,
    9. //即现在str[1]和str[3]都指向了同一地址
    10. str[2] = p[1] + 3;//p[1]存储"Nanjing"字符串的地址,为(char *)型,加三的效果为:
    11. //+sizeof(char)*3,
    12. //故str[2]存储了"Nanjing"字符串中的"jing"地址
    13. str[3] = p[0] + (str[2] - str[1]);//str[3]指向从p[0]开始(也就是*p,也就是str[2])的偏移量
    14. //为(str[2]-str[1])的地址~ str[2]指向"jing",str[1]指向str[3],
    15. //也就是"Nanjing",所以str[3]指向"jing"的"g"地址
    16. printf("%s\n", str[0]);
    17. printf("%s\n", str[1]);
    18. printf("%s\n", str[2]);
    19. printf("%s\n", str[3]);
    20. return 0;
    21. }

     图示:

    1. char* str[] = { "welcome","to","Fortemedia","Nanjing" };
    2. char** p = str + 1;

    得到:

    执行下一句,画出(*p++) + 2

     将其赋值给str[0]

    1. str[0] = (*p++) + 2;
    2. 画出*(p+1)

    1. str[1] = *(p + 1);赋值
    2. 画出p[1] + 3

     

    1. str[2] = p[1] + 3;赋值
    2. 画出 p[0] + (str[2] - str[1])

    我们可以得到str[2] -str[1] = 3 , 在两个指针指向同一片连续的存储空间时 , 是可以相减的 , 相减为两指针间差了几个元素 ,很明显差了三个 , 再将p[0]+str[2] -str[1]的值赋给str[3] ,如下图 :

  • 相关阅读:
    [ Shell ] 两个 case 实现 GetOptions 效果
    Docker容器化技术(从零学会Docker)
    C++ 友元
    嘉兴桐乡考证培训-面试高手是这样划分备课时间的!
    allegro中shape的一些基本操作(二)——铜皮添加网络、合并shape
    深入解析Laravel框架:目录结构全解析
    Intel汇编-内联汇编使用全局变量
    Python+django+vue信息技术学习网站
    思腾云计算
    持续集成部署 - Jenkins 配置使用远程服务器的 Docker 执行构建任务
  • 原文地址:https://blog.csdn.net/weixin_51609435/article/details/126145701