今天小编遇到一题看似很简单但是很多大佬都做不出的程序结果题
#include<stdio.h>
void swap(char **s);
void main()
{
int i;
char *str[5]={"Love","Happy","Sad","Scared","Angry"};
swap(str);
printf("%s\n",*str);
}
void swap(char **s)
{
char *q;
int i,j;
for(i=4,j=0;i>2;i--,j++)
{
q=*s;
*s=*(s+i-j);
*(s+i-j)=q;
s++;
q++;
printf("%s\n",q);
}
}
我们先看看指针的传参:在swap函数中用形参二级指针**char接收了指针数组*str[5],两者指向同一个地址,大家不妨把形参看作新设的一个变量,只不 过把实参通过 = 赋值给了(可以重名的)形参。
接下来是for循环的交换:
q=*s;
*s=*(s+i-j);
*(s+i-j)=q;
1.第一次s中的,(指向第0个元素s[0],即"Love",)的指针所指向的内容(可以简单地认为前面有 * 就是改变内容)和指向(第i=4个元素s[4],即“Angry”,)的指针所指向的内容交换了,实参中的Love和Angry也交换了,
此时需要辨析的是
q=s;
s=s+i-j;
s+i-j=q;
只不加*只交换形参指向的地址是不起作用的,因为虽然形参和实参指向同一段内存空间但只改变自己不改变指向的内容无法传参
s++;
q++;
s++使s向后跳s的类型的字节长度,即char *的长度,所以跳过Love来到了Happy的首地址 ,但形参指向的改变并不改变str的指向,即实参指针数组名str仍然指向首地址,若此时puts(str),会得到Angry,而puts(s)会得到Happy.
q++使p向后跳char 的字节长度即q原来指向Love的L此时指向o。
2.第二次给q赋值s指向的内容,s++在这里才影响到了q,q指向Happy中的H.
q=*s;
*s=*(s+i-j);
这次与 *s交换的 * (s+i-j)要额外注意,因为s++,s+i-j此时并不是指向第3-1个元素Sad而是第1+3-1个元素(s++的影响容易忽略)
接下来就不再赘述
回到main函数中,*str此时输出了什么呢,因为实参的指向还是原来的,并没有发生改变,所以输出指针数组的第一个元素,但因为在函数中发生了交换,此时的第一个元素变成了Angry,
即最后答案是
ove
appy
Angry
这道学解上的难题看懂了吗,记得点赞哦