今天看到一个巨变态和奇葩的C++题目,花了很久才弄懂为什么。手头书上的答案还有误,因此特意记录下来。

题目如下:

判断输出:

#include<stdio.h>
int main()
{char *str[]={"Welcome","to","Fortemedia","Nanjing"};char **p=str+1;str[0]=(*p++)+2;str[1]=*(p+1); str[2]=p[1]+3;str[3]=p[0]+(str[2]-str[1]);printf("str[0]=%s\n",str[0]);printf("str[1]=%s\n",str[1]); printf("str[2]=%s\n",str[2]); printf("str[3]=%s\n",str[3]); return 0;
}

在逐步分析之前先举个例子:

对于常规的指针来说,比如:

int b=1;
int* a=&b;

那么输出*a,是1;输出a,是b的地址。

但是,char*是个特殊的指针例子。比如:

char *str="this is a test";

这时候,输出*str,只会输出“t”;

输出str,显示的并不是地址,而是“this is a test”(完整的字符串)!

如果先执行str=str+2,那么输出str,会输出“is is a test”;输出*str,会输出“i”。


现在开始一句一句看上面的题目:

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

第一句*str[ ],定义的是一个指针数组,数组的名字叫str,每个元素是一个字符串指针;

第二句,**p=str+1,那么这个p,是一个指针,指向了另一个指向字符串的指针。

(这里隐含了一个重要的信息!即:p=&str[1];)

那么这时,*p指向的是“to”的首地址:

如果输出*p,输出的是“to”;

如果输出**p,输出的是“t”;

如果输出p[0],会输出“to”(p[0]就相当于*p了!这就好比数组a[10],输出*a其实就是a[0],一码事)

如果输出p[1],会输出“Fortemedia”

如果输出p[2],会输出“Nanjing”

然后:

str[0]=(*p++)+2;

这句话有个陷阱:

*p++究竟是“ (*p)++ ”  还是“  *(p++) ”?

查阅资料可知,++的优先级高于*,因此是p++(p自增),而不是(*p)++(不是*p自增)

因为是后置加法,返回的是未自增以前的p!

str[0]=(*p++)+2等同于:

1. str[0]=*p+2;(这里的p是自增以前的p,str[0]在加2前,指向“to”首地址,加完2,指向的是to中的第三位,即结尾符“\0”)

2. p=p+1;(同样隐含了一个重要信息:p=&str[2],这个之后会用到!!留意!;p此时指向了一个指向字符串"Fortemedia"的指针str[2])。

那么输出str[0],显示为空,其实是输出的“\0”。


ps:关于上面这个,我要说一点:有的辅导书上写的是错的,他们说,先p自增,跑到了Fortemedia这里,即str[2],然后又加了个2,跑到了str[4],而str[ ]数组只有1到3,str[4]是空,所以str[1]被赋值为空。

这纯粹是胡说八道。说明写书的人自己都不懂。如果不信,可以把上面的str换一下:

char *str[]={"Welcome","toa","Fortemedia","Nanjing"};(即把第二个to改成toa)

那么执行str[0]=(*p++)+2;输出str[0],不是空,而是a。

符号优先级代表的是结合的优先级,而不是执行顺序。str[0]=(*p++)+2并不代表我要先把p++再取*再加2;而是意味着是p自增,而不是*p自增。实际上是先*再+2,最后p自增)


之后:

str[1]=*(p+1);

我们知道p已经指向了str[2]的地址,也就是指向了一个指向字符串"Fortemedia"的指针。p+1,是str[2]的地址加1,那么返回str[3]的地址,取*,得到指向“Nanjing”的指针,因此输出str[1],是“Nanjing”。

再之后:

str[2]=p[1]+3;

p此时指向一个指向Fortemedia的指针,p[0]则相当于是*p,是指向Fortemedia的指针。p[1]指向了最后的Nanjing字符串首地址。

p[1]+3,得到指向“jing”的首地址的指针,返回str[2]中

注意到前面的重要信息,p=&str[2],str[2]改变了,p也随之改变,因此p指向了一个指向“jing”的指针。

事实上这句话与*p=p [1]+3等价。

输出str[2],结果为“jing”。


最后:

str[3]=p[0]+(str[2]-str[1]);

我们要知道,p[0]相当于是*p,是指向“jing”的指针;

str[2]也是指向“jing”,str[1]我们刚刚知道,指向“Nanjing”。

(str[2]-str[1])得到3。

p[0]指向jing的指针,再加3,指向了g,因此str[3]输出g。

经典奇葩面试题:C++中字符串的数组指针与指针数组相关推荐

  1. ajax参数中字符串最大长度_6.7 C++数组名作函数参数 | 求3*4矩阵中最大的值

    C++用数组元素作函数实参 C++中实参可以是表达式,而数组元素可以是表达式的组成部分,因此数组元素可以作为函数的实参,与用变量作实参一样,将数组元素的值传送给形参变量. C++也可以用数组名作函数参 ...

  2. 经典Java面试题-Java中Char类型的运算

    [面试原题] 假设y是字符类型,初始化值为'b',那么以下语句输出的结果是什么? A.  System.out.println(++y); B.   System.out.println(y+1); ...

  3. 一道十分经典的intern面试题(String字符串)让你彻底搞懂intern方法

    首先我觉得要看懂这道题还得知道inren()方法的一些知识,还要知道new String("ab")到底创建了几个对象. 一.intern()方法的理解(重难点) 1.intern ...

  4. C语言试题十六之写删除字符串中指定下标的字符。其中,a指向原字符串,删除后的字符串存放在b所指的数组中,n中存放指定的下标。

    1. 题目 请编写一个函数void function(char a[],char b[], int n),其功能是:删除字符串中指定下标的字符.其中,a指向原字符串,删除后的字符串存放在b所指的数组中 ...

  5. java char 计算_经典Java面试题之Java中Char类型的运算

    经典Java面试题之Java中Char类型的运算 char在java中称为"字符型",占2个字节.本文是百分网小编搜索整理的关于经典Java面试题之Java中Char类型的运算,有 ...

  6. 一道非常经典C++面试题|大厂面试

    问题1:小伙伴问我,这个unique_ptr出了作用域为什么没调它的析构函数呢? 问题2:第一个运行结果是什么?为什么? 我把问题抛到群里讨论,让大家一起思考,大家可以先思考一下: C++背景知识 C ...

  7. 100条经典C笔试题

    题目来源: 1.中兴.华为.慧通.英华达.微软亚洲技术中心等中 外企业面试题目: 2.C 语言面试宝典(林锐<高质量编程第三版>). 说明: 1.部分C 语言面试题中可能会参杂部分和C++ ...

  8. java中字符 的含义 有什么作用_Java中字符串常见题之String相关讲解

    今天给大家带来的是在面试中经常被问到的一道题: 无论在Java还是Android中,String是一个很常见的类,但是大家真的很了解吗,我这里有几个题: 1. String str1 = " ...

  9. 一个经典编程面试题的“隐退”

    [转] 一个经典编程面试题的"隐退" 作者:童燕群 | 发布日期:三月 22, 2014 本文由 伯乐在线 – 王伯 翻译自 The Noisy Channel. 面试程序员很困难 ...

最新文章

  1. pycharm中报错:Error: failed to send plot to http://127.0.0.1:63342
  2. 设计模式=相似模式区别
  3. 深度学习核心技术精讲100篇(五十九)-多业务融合推荐策略实战应用
  4. 中国34城最全剖析:深圳、天津的短板与不足,何时才能补?
  5. springboot + mybatis + gradle项目构建过程
  6. SonarQube中配置c语言/c++语言代码规则插件
  7. mysql使用navicat(建表前与建表后)添加时间戳(创建时间、自动更新时间)
  8. 在ECSHOP后台左侧导航中增加新菜单
  9. win10计算机更新后网络卡,win10电脑更新完卡死 win10电脑更新完卡死解决办法
  10. 使用Visual Studio OnlineSQL Server数据库源控制:Git
  11. Jmeter中Websocket协议支持包的使用 (转)
  12. 关于jdk11没有jre
  13. iphone6主板注释
  14. Xtrabackup 安装以及 mysql 使用 Xtrabackup 物理备份过程记录
  15. Kodu程序的菜单---Kodu少儿编程第七天
  16. 基于VC++和QT实现的图的可视化工具
  17. 【读书笔记】周志华 机器学习 第二章 模型评估和选择
  18. LCD-TFT 驱动原理
  19. JavaScript时间格式
  20. 解决安装VS2022时,出现未能安装包“Microsoft.VisualCpp.Redist.14,version=14.32.31332,chip”=x86

热门文章

  1. 微信小程序 选项卡(数据双层循环)
  2. mysql添加外键语句
  3. python爬取虎牙弹幕礼物数据
  4. 左移右移对原数的影响
  5. 2018-2019-2 《网络对抗技术》Exp5 msf 20165222
  6. visio常用快捷键_Visio 快捷键
  7. 好心情:别在该躺平的时候动脑子,10种方法让大脑高效休息
  8. 升序降序排序测试方法
  9. Redis安装与部署新手入门教程
  10. 【TypeScript笔记】03 - TS类型声明文件