Exercise 6:阿里巴巴面试题
求下列代码的执行结果
#include <stdio.h>
int main()
{
char *a[] = {"work","at","alibaba"};
char**pa = a;
pa++;
printf("%s\n", *pa);
return 0;
}
答案速查:
分析:
char *a[] = {"work","at","alibaba"};这条代码不是把三个字符串放入a中,而是a指针数组中存放着的地址指向字符串的work首字母w的第一个字节,at首字母a的第一个字节alibaba首字母a的第一个字节
VS2022打开内存输入&a
发现存放的地址0x009a7bcc,0x009a7bd4,0x009a7bd8是连续的,对应三个字符串的首字母的地址
转到地址0x009a7bcc
每一个字符串的结尾都跟着\0
pa的类型是char**,是二级指针(潜台词:二级指针指向一级指针),即pa指向a这个一级指针,一级指针指向字符串的首字母
pa++,二级指针指向a这个指针数组的第二个元素,第二个元素(一级指针)指向第二个字符串的首字母
结果输出at
★(HARD)Exercise 7
求下列代码的执行结果(printf中有表达式过于复杂,→点击查看优先级←)
#include <stdio.h>
int main()
{
char* c[] = { "ENTER","NEW","POINT","FIRST" };
char** cp[] = { c + 3,c + 2,c + 1,c };
char*** cpp = cp;
printf("%s\n", **++cpp);
printf("%s\n", *-- * ++cpp + 3);
printf("%s\n", *cpp[-2] + 3);
printf("%s\n", cpp[-1][-1] + 1);
return 0;
}
答案速查:
分析:
y由前三行可画:
优先级:++和-- > *(解引用) > +
注意:一次解引用是从指针指向的位置到另一个位置
① printf("%s\n", **++cpp);
由于优先级:++> *(解引用) ,因此cpp先减1再两次解引用(此时cpp的值已经变动!会影响到下一个printf打印的内容)
结果是POINT
② printf("%s\n", *-- * ++cpp + 3);
重点在分析运算顺序!!!
从cpp开始,cpp左侧为++,右侧为+,显然++优先运算,指向c+1
*紧邻++,,且比+3优先级高,因此发生一次解引用,c+1的值被取了出来
*紧邻--,且比+3优先级高,因此c+1的值减了1,所以指向c[0]
*紧邻--,且比+3优先级高,因此c[0]被解引用,其值指向ENTER的E
最后+3,c[0]存储的ENTER首字母的E的地址+3,变成ENTER第二个E的地址
结果为ER
③ printf("%s\n", *cpp[-2] + 3);
解引用是取出内存地址指向的值,首先*cpp[-2]+3的等价写法为**(cpp-2)+3,cpp原本指向cp[3],但现在为cpp-2,因此指向cp[0],由于*优先级比+高,先执行*(cpp-2),解引用得到的是cp[0]存储的值,对cp[0]存储的值(c[3]存储的地址)再一次解引用*,得到的是c[3]的值(存储的是FIRST首字母F的地址),接着执行+3,即FIRST首字母的地址+3为S的地址,运算结果相当于printf("%d",FIRST的S的地址);最终以%d打印(即从FIRST的S开始)结果是ST
结果为ST
④ printf("%s\n", cpp[-1][-1] + 1);
cpp[-1][-1]为(*(*cpp-1)-1)+1
分析同上
结果EW