北邮C++实验课:字符串变量的交换——真正能证明指针是不是学会的题(多种解决方案和分析)

此题有原创代码有各方搜集的代码,但所有的代码都是我自己亲自分析解析的。(急着交作业的同学可以转到大标题三下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验证,可直接用。

二级指针也就是一次解引用指向地址,第二次解引用才指向值,根据上面错误代码分析:发现,函数只能交换指针的指向,所以我们要利用指针的话——只有直接交换指针本身的地址才可以实现字符串交换,所以想交换指针本身,那就是在利用一个指针指向其地址,然后对其交换,或者像法一一样利用引用,因为引用本质上用的就是地址。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

芝麻柚

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值