代码改变世界

2012搜狗校园招聘笔试题(2)

2017-05-30 11:32  tlnshuju  阅读(170)  评论(0编辑  收藏  举报

        本文是自己学习所做笔记。欢迎转载,但请注明出处:http://blog.csdn.net/jesson20121020   

问题描写叙述:

           以下的程序应该输出多少?

char *c[] = {"ENTER","NEW","POINT","FIRST"};
char **cp[] = {c+3,c+2,c+1,c};
char ***cpp = cp;

int main(void){
	printf("%s",**++cpp);
	printf("%s",*--*++cpp+3);
	printf("%s",*cpp[-2] + 3);
	printf("%s\n",cpp[-1][-1]+1);
	return 0;
}

问题分析:

          这是一个考查指针算术运算的题。有关于指针的介绍。请看我另外几篇博客http://blog.csdn.net/jesson20121020/article/category/2604105

首先。要弄清楚这几个变量究竟代表什么:

c 是一个二维的数组,元素类型为char,共同拥有四行,另外,数组名c也代表数组的首地址
cp是一个指针。其类型为char **[],其指向的类型为char *[],cp的值也就是cp指向的内存地址为{c+3,c+2,c+1,c}
cpp相同是一个指针。其类型为char ***,其指向的类型为char **。cpp的值为cp也就是指针cp的地址。
例如以下图所看到的:

接着,就是分析指针cpp的几个算术运算和间接运算符*。这里要注意运算符优先级,当中++ 或 -- 和 * 优先级一样,同一时候出现时,採用就近原则,*、++、--、的优先级要比 + 或 - 优先级高,还有()、[]优先级最高。
最后,就是运用优先级顺序。分别计算出各个表达式所指的内容却可。


解决思路:

          总共同拥有四个表达式。一个一个分析:

1. printf("%s",**++cpp);  

               **++cpp,为了看的更清楚,能够运用优先级顺序加上括号,变成*(*(++cpp)),也就是先计算++cpp,由于cpp的值为cp(指针cp的地址。这里就简单用cp来表示),自加1后变成了cpp的值变成了cp+1。也就此时的指针cpp指向了指针cp地址的下一个内存单元。然后再计算*(++cpp),这是一个指针表达式。结果为cpp指向的东西,在这里就是c+2,最后再做一次*运算 。也就是指向地址c+2处。以字符串的形式输出,在这里,(**++cpp)就是存储PONIT的首地址,所以第一个输出为PONIT。

2. printf("%s",*--*++cpp+3);

              *--*++cpp+3。 相同,能够写成这样的形式:(*(--(*(++cpp))))+3 。括号比較多,一层一层分析,++cpp 也是指向了其下一个地址,和上个分析一样,这里。指向了指针cp地址的后两个单位的位置( 由于cpp之前已自加1),在这里就是指向了内容为c+1的地址,然后再计算*(++cpp)。结果为cpp指向的东西,显然,在这里就是c+1。--(*(++cpp))。也就是将c+1减1,为c;*(--(*(++cpp))) 指向地址为c的内存单元处,在这里也就是ENTER的首地址。最后,再加上3。则此时又指向了字母E处。输出结果,就是ER。

3. printf("%s",*cpp[-2] + 3);

              这个和第二个类似。差别在于,cpp[-2]指的是指针cpp所在内存地址向前的两个单位的地址,在这里就是指向了内容为c+3的地址,*cpp[-2]就是指向内存地址为c+3的内存单元处,在这里也就是FISRT的首地址,最后加上3,则指针向后移动了3个单位,即指向也字母S处。输出结果,为ST。

4. printf("%s\n",cpp[-1][-1]+1);

              通过上述三个的输出的分析。这个也easy,由于运行第一、二个输出语句后,指针cpp向后共移动了两个单位,即指向了内容为c+1的地址,所以cpp[-1]也就是指指针cpp的前一个内存单元,即指向了内容为c+2的地址单元,接着。分析cpp[-1][-1]。非常明显,cpp[-1][0]也就是指向了地址为c+2的内存单元。那么,cpp[-1][-1]就指向了地址为c+2的前一个内存单元处,也就是指向了地址为c+2 -1 = c+1的内存单元处,即指向了NEW的首地址,最后。加1,就指向了字母E处。输出结果,为EW。


综上。终于的输出结果为POINTERSTEW

真正运行下上述代码,验证结果:

#include <stdio.h>
char *c[] = {"ENTER","NEW","POINT","FIRST"};
char **cp[] = {c+3,c+2,c+1,c};
char ***cpp = cp;

int main(void){
	printf("%s",**++cpp);
	printf("%s",*--*++cpp+3);
	printf("%s",*cpp[-2] + 3);
	printf("%s\n",cpp[-1][-1]+1);
	return 0;
}
运行结果: