经典奇葩面试题:C++中字符串的数组指针与指针数组
发布日期:2021-06-29 07:20:55 浏览次数:2 分类:技术文章

本文共 2201 字,大约阅读时间需要 7 分钟。

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

题目如下:

判断输出:

#include
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。

转载地址:https://blog.csdn.net/zkk9527/article/details/90181505 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:C和C++重难点复习笔记(一)【面向过程】
下一篇:SLAM14讲学习笔记(十四)ch13 建图(代码详述带注释)

发表评论

最新留言

关注你微信了!
[***.104.42.241]2024年04月26日 01时38分01秒