算法要求:编写一个函数,将指向两个数组的指针交换。
参考博文:c语言 通过调用函数交换两个实参指针的指向地址_交换两个指针的地址-CSDN博客
数组元素初始化:
char a[4]={'r','s','t','u'};
char b[4]={4,3,2,1};
初始程序如下:
#include<stdio.h>
swap( char *t1,char*t2)
{ char *temp;
temp=t1;
printf("子函数temp=%d,子函数*temp=%d,&temp=%d\n",temp,*temp,&temp);
printf("交换前子函数t1=%d,子函数*t1=%d,&t1=%d\n",t1,*t1,&t1);
printf("交换前子函数t2=%d,子函数*t2=%d,&t2=%d\n",t2,*t2,&t2);
t1=t2;
t2=temp;
printf("交换后子函数t1=%d,子函数*t1=%d,&t1=%d\n",t1,*t1,&t1);
printf("交换后子函数t2=%d,子函数*t2=%d,&t2=%d\n",t2,*t2,&t2);
}
int main(){
int i;
char a[4]={'r','s','t','u'}; //会通过%d自动转码 为ASCII码数值
char b[4]={4,3,2,1};
char *p=&a[0];
char *q=&b[0];
printf("交换前&a[0]=%d,p=%d,*p=%d &p=%d\n",&a[0],p,*p,&p);
printf("交换前&b[0]=%d,q=%d,*q=%d,&q=%d\n",&b[0],q,*q,&q);
// printf("p=%d *p=%d\n\n ",p,*p);
swap(p,q); //调用该函数
printf("交换后p=%d,*p=%d",p,*p);
printf("交换后q=%d,*q=%d\n",q,*q);
for(i=0;i<=3;i++) //通过指针变量自增输出交换后的两个数组
{
printf("a[%d]=%d ",i,*p);
p++;
printf("b[%d]=%d\n",i,*q);
q++;
}
}
程序运行分析图如下:
示意图中上标是指向地址,下标是自身地址。图中的箭头都是指向该地址上的数据也就是上标,如p交换前568指向114,在图中我并没有画准确,所以补充说明下。
发现问题:形参和实参的自身地址不同,只交换了两个形参的指向地址
情况分析如下:程序改变了t1和t2的指向,但我们需要的是改变p1和p2的指向,
我反复思考,发现这个函数是没有问题的,他确实改变了两个指针的指向,所以问题就出现在参数的传入上。传的的p和q的指向地址,那自然只是在形参上互换了这两个,跟p和q自身一点关系都没有。所以要把p和q的自身地址传进去才行。
解决过程:
p和q的自身地址是&p,&q
1.将swap(p,q)改为swap(&p,&q)
此时会涉及到函数形参定义是一元运算符而实参是二元运算符产生冲突的问题,
我们知道,地址就是指针,而&p,&q是指针的自身地址也就是指针的指针,所以&p,&q是二元运算符与**p,**q相对应
2.所以需要将函数的参数定义修改
从swap( char *t1,char*t2)改为swap( char **t1,char**t2)
3.交换原理:t1表示形参t1的指向地址,&t1表示形参t1的自身地址,*t1表示形参t1的指向地址的数据-->也就是实参p的指向地址。目的是交换实参p和q的指向地址,故只要交换*t1和*t2的值即可
修改后的程序如下:
#include<stdio.h>
swap( char **t1,char**t2)
{ char *temp;
temp=*t1;
printf("子函数temp=%d,子函数*temp=%d,&temp=%d\n",temp,*temp,&temp);
printf("交换前子函数t1=%d,子函数*t1=%d,&t1=%d\n",t1,*t1,&t1);
printf("交换前子函数t2=%d,子函数*t2=%d,&t2=%d\n",t2,*t2,&t2);
*t1=*t2;
*t2=temp;
printf("交换后子函数t1=%d,子函数*t1=%d,&t1=%d\n",t1,*t1,&t1);
printf("交换后子函数t2=%d,子函数*t2=%d,&t2=%d\n",t2,*t2,&t2);
}
int main(){
int i;
char a[4]={'r','s','t','u'}; //会通过%d自动转码 为ASCII码数值
char b[4]={4,3,2,1};
char *p=&a[0];
char *q=&b[0];
printf("交换前&a[0]=%d,p=%d,*p=%d &p=%d\n",&a[0],p,*p,&p);
printf("交换前&b[0]=%d,q=%d,*q=%d,&q=%d\n",&b[0],q,*q,&q);
// printf("p=%d *p=%d\n\n ",p,*p);
swap(&p,&q); //调用该函数
printf("交换后p=%d,*p=%d",p,*p);
printf("交换后q=%d,*q=%d\n",q,*q);
for(i=0;i<=3;i++) //通过指针变量自增输出交换后的两个数组
{
printf("a[%d]=%d ",i,*p);
p++;
printf("b[%d]=%d\n",i,*q);
q++;
}
}
解决结果:
可以看到,形参t1和t2的自身地址&t1,&t2和指向地址t1,t2都未发生改变,改变的是t1和t2的指向地址的数据*t1,*t2即p和q的指向地址p,q。如下图所示