此题有原创代码有各方搜集的代码,但所有的代码都是我自己亲自分析解析的。(急着交作业的同学可以转到大标题三下copy)
一、题目描述:
编制程序,调用指针作为参数的函数,实现下面两字符串变量的交换。 char* ap="hello"; char* bp="how are you"; 交换的结果为:ap 指向"how are you",bp 指向"hello"。 (注意:输出语句中的;和.为英文符号)
输入
无
输出
ap指向how are you;
bp指向hello.
二、问题代码:
#include<iostream>
using namespace std;
void swap(char *a, char *b)
{
char *c;
c = a;
*a = *b; //在这里中断
*b = *c;
}
int main()
{
char *ap = "hello";
cout << *ap;
char *bp = "how are you";
swap(ap, bp);
cout << "ap指向" << ap << ";" << endl;
cout << "bp指向" << bp << ".";
system("pause");
return 0;
}
这是我第一次的代码
首先编译器运行会中断,显示的是访问冲突,这里我很纳闷,老师解释这里*ap,和*bp都看成一个常量,此时这两个字符串是存在于代码区的(代码区是什么书上没写,可以参考黑马程序员C++教程)但我们目前不用理解代码区什么意思,就知道此时这个字符串只能读不能写,跟用const修饰一个变量一样,所以此处会报错,访问冲突(也就是不让访问)。
第二次代码:
#include<iostream>
using namespace std;
void swap(char*ap, char*bp)
{
char*cp;
cp = ap;
ap = bp;
bp = cp;
}
int main()
{
char*ap = "hello", *bp = "how are you";
swap(ap, bp);
cout << ap << endl;
cout << bp;
system("pause");
return 0;
}
这次代码发现他是无法真正实现交换的。这个不能实现交换的原理就类似与值传递,在函数中我们只能通过一种作用把指针的指向改了,从而来实现值的交换。这里没能进行地址交换,是因为在函数中它是相当于复制出了相应的a和b,在函数中进行了交换,但是函数运行结束,内存释放了,这两个看似交换的变量也没了,所以没有实现真正的交换。
网上代码,但是其实是没有真正理解的:
using namespace std;
void swap(char*ap, char*bp)
{
char*cp;
cp = ap;
ap = bp;
bp = cp;
}
int main()
{
const char*ap = "hello", *bp = "how are you";
swap(ap, bp);
cout << ap << endl;
cout << bp;
system("pause");
return 0;
}
看似下面代码只是多了const,但是惊奇地发现,这个代码竟然实现了交换!怎么做到的,而且const在我们学的里面也不是这么用的啊,const不是不能进行修改吗。
其实在程序中增加断点(你不会还不会加断点吧……),就可以发现,程序根本没有执行我们写的swap函数,而是执行了自己库里面的swap函数。这里作者只是耍了个小聪明蒙混过关,其实可能作者自身也没意识到这里的问题,至于为什么两个代码就差个const差别这么大,应该是我们写的swap函数要求的数据类型不是const修饰的,所以这里发生了重载。
三、正确代码:
正确代码也是可以通过两种形式实现的:
1、通过引用实现:
#include <iostream>
using namespace std;
void swap(char * & a, char * &b)
{
char * temp =a;
a=b;
b=temp;
}
int main()
{
char * a=”Hello”;
char * b=”How are you!”;
swap(a,b);
cout<<a<<endl<<b<<endl;
return 0;
}
(上面的代码没有从PTA验证,功能完全可以实现,可能需要读者自行修改输出形式)
这里用到的是引用,引用其实就是这个指针的别名,直接通过引用进行赋值,从而直接通过函数交换到真正的地址。引用的简洁高效体现于此!
2、通过二级指针:
#include<iostream>
using namespace std;
void swap1(int **t1, int **t2)
{
int *temp;
temp = &(**t1);//t1指针本身地址
*t1 = &(**t2);
*t2 = temp;
}//完成交换
int main()
{
int a = 5, b = 6;
int *pa, *pb;
pa = &a, pb = &b;
swap1(&pa, &pb);//传入指针本身地址
cout << *pa << *pb;
system("pause");
return 0;
}
此代码通过pta验证,可直接用。
二级指针也就是一次解引用指向地址,第二次解引用才指向值,根据上面错误代码分析:发现,函数只能交换指针的指向,所以我们要利用指针的话——只有直接交换指针本身的地址才可以实现字符串交换,所以想交换指针本身,那就是在利用一个指针指向其地址,然后对其交换,或者像法一一样利用引用,因为引用本质上用的就是地址。