分享
 
 
 

深入C++指针(1)

王朝c/c++·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

自2001年大学毕业后,我使用C++就开始变得比较少了。那曾经为C++疯狂的日子已经永远的留在了那个熟悉的校园。就编程语言而言,C++对我无疑是最有亲和力、诱惑力的。虽然现在一直投身在java方面,但那份迷恋C++的情感压根就没有变过,一直无法割舍。常常会萌发在C++方面再做点什么的念头。渐渐地便有了在网上发表文章的念头。“我眼中的C++指针”系列是本人结合参赛经验和实际开发应用,从那个一直牵挂着的快要被遗忘的角落拣回的点点滴滴。本篇是第一篇,介绍指针的本质是什么。

在相当一部分的C++教程中,讲到指针时,基本上都会举swap(int a,int b)这个 数据交换的例子。我也同样愿意举这个例子作为讲述指针的开始。

下面是类的代码内容:

//……限于篇幅,只留说明问题的部分内容……

定义部分:

public:

void swap(int a,int b);

实现部分:

void CPointerResearch::swap(int x,int y){

int nTmp = x;

x = y;

y = nTmp;

}

下面是测试数据及结果:

输入:

100, 200

输出(执行swap函数后):

100, 200

Press any key to continue

可以很清楚的看出,并没有实现数据交换。

我们来假想一下程序员写这样程序时的心里:有两个小框,甲框放数字为100的卡片,乙框放数字为200的卡片,现将两张卡片交换一下位置,变成甲框存放数字为200的卡片,乙框存放数字为100的卡片。

这样的想法有问题吗?答案很明确,一点点问题都没有!想法完全正确,他(她)只要确实是这样做的,卡片交换就一定能成功。但为什么上面的程序模拟这样的执行过程,结果却不是想要的呢?要想彻底弄明白这个问题,我们必须认识问题的根本,即这个问题的本质是什么,这才是真正解决问题。

我们来深入分析一下上面那个看似简单的假想情景。第一,有两个框,这是确定的事实,毋庸置疑。第二,框里都装有卡片,并且上面的数字不同,这个是不争的事实。第三,交换卡片过程中,虽然两个框都没挪动,但里面的卡片都有挪动。第四,卡片挪动是从一个框挪到另一个框。正是有了这四点作保证,卡片才得以成功交换。换句话说,上面的数据交换程序的执行交换过程如果满足这四个条件的话,计算机执行后输出的结果就一定是我们期待的正确结果。那么,至此出错原因已很明确,就是计算机执行程序的过程中,上面这四点至少有一点一定不符合。下面一一分析。

第一, 从输入条件看。

输入条件是int a =100;int b= 200;从这两个C++语句我们可以看出,两个“框”已经有了,分别是a和b,也就是说具备了第一个条件。此外,甲框(a)放了数字为100的卡片(int a=100;), 乙框(b)放了数字为200的卡片(int b=200;),这说明第二个条件也具备。从输入条件已经看不出什么其它的有用的信息。至此我们已经可以判断出问题出在后两个条件有不满足的地方。

第二, 从swap函数体看。

函数体 int nTmp = x; x = y; x = nTmp;是最典型的只用三行代码就实现数据交换的代码。没问题,在执行这三行代码前和执行后分别打印输出就可以看得一清二楚,确实实现交换了。这说明上面的第四个条件也满足,因为这三行代码就是“从甲框拿x卡片放到地上,再把乙框的y卡片放入甲框,最好将地上的那张卡片(就是x卡片)拣起来放到乙框中去”。那么,到现在可以说明问题出在第三个条件不满足。我们再继续分析下去。

第三, 从swap函数声明看。

从数据交换的程序代码看,也就只剩这么一点东西还没有去分析一下。我们的执行过程其实又有几个分步骤:

首先,输入:int a= 100; int b= 200;这只是赋值操作,肯定没有问题。

其次,执行:步骤1,为调swap(int x,int y)函数做准备,将a传给x,b传给y。

步骤2,执行swap(x, y),就是执行函数体内容。步骤2在上面已经得到验证,没问题。

最后,执行完毕在主函数里输出a和b:100,200,这是调C++标准输出函数输出的,提供什么数据就如实地输出来。这也没问题。

至此,问题已经可以定位,就在“其次”里的“步骤1”!对这一步的执行过程再继续细分,就是:将甲框(输入的a)的数字为100的卡片放到丙框(swap函数的参数x)注1, 将乙框(b)的数字为200的卡片放到丁框(swap函数的参数y)。程序接下来就是执行“其次”里的“步骤2”,也即进入函数体执行,这时候在悄悄的把丙框和丁框的卡片相交换。可见原来交换的是丙框和丁框!甲框和乙框原来是什么样还是什么样。这当然不会看到期望的输出。

所以解决问题的根本是必须要“找对框”,只交换想要交换的“框”。对这个“找对框”的真正理解程度会直接反映出对指针的真正理解程度。 这样,可能的解决方法比如:

基于指针的swap方法(直接拿甲框和乙框的卡片并进行交换,根本就没有丙框和丁框):

void CPointerResearch::swap(int* x,int* y){

int nTmp = *x;

*x = *y;

*y = nTmp;

}

基于引用的swap方法(不直接用丙框(而是引用到甲框)和丁框(而是引用到乙框)):

void CPointerResearch:: swap (int& x,int& y){

int nTmp = x;

x = y;

y = nTmp;

}

注1:本文举的假想例子主要是为了说明问题,但例子不一定很贴切。“将甲框(输入的a)的数字为100的卡片放到丙框(swap函数的参数x)”这句话,更贴切的说应该是“甲框有跟线系在数字为100的卡片上,现在执行“a传给x”操作,就是说丙框要拉一根线出来也系到那张数字为100的卡片上”。

本篇内容强调的就是一点,“什么是指针?指针的本质是什么?”。理解指针的本质是学习指针的关键所在。特别是初学指针者,如果能把这个swap函数真正搞明白,那么对指针的理解应该说已经有了一定的功底。如果很浮躁或很肤浅的去看待指针,是不会真正掌握指针的丰富内涵的。用指针,要用,那就要用到“没指针,就感觉不知道如何是好”这个地步。否则用指针也没太大的意思,又容易出错,不止怎么排除,自己可能兴趣也不高。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有