前言
从大学到现在的时候一直在用c, c++接触的甚少,并且也从未系统的学习过,因此最近一直阅读c++primer(第五版)。
问题
在看到第六章的时候碰到的一道练习题:要求用递归输出vector的对象内容,当时一考虑后写下的代码:
#include "common.h"
int print(vector<int> ivec, vector<int>::iterator iter)
{
if(iter != ivec.end())
{
cout<<"recursive output:"<<*iter<<endl;
print(ivec, ++iter);
}
return 0;
}
int main()
{
int arry[5] = {1,2,3,4,5};
vector<int> ivec1(arry, arry+5);
print(ivec1, ivec1.begin());
}
编译运行后发现递归一直在进行,认真查看了代码,在当时并没有看出什么问题。无奈之下,只能通过gdb调试,在函数print打了断点了,发现递归函数print每次传的ivec.end()都不一样,所以导致了递归的基准情形失去了作用,所以递归函数无法返回。
解决
为什么print函数的形参ivec.end()每次都不一样呢?其实在c++prime里面已经明确的说明了,函数的形参是通过传递的实参进行初始化,这就是说,print函数中的形参ivec每次都被初始化赋值了,而vector是支持初始化赋值,此时类似新创建了一个vector,并且用上一个的vector进行拷贝初始化,这也间接导致了ivec.end()每一次都不一样。在找到问题后,修改后也就容易了。
int print(const vector<int> &ivec, vector<int>::iterator iter)
{
if(iter != ivec.end())
{
cout<<"recursive output:"<<*iter<<endl;
print(ivec, ++iter);
}
return 0;
}
递归函数print用了vector的引用,这也就保证了每次传递到函数里的形参都指向同一个vector对象。编译运行后,问题解决。
总结
其实这是一个很小,很基础的问题,可问题的关键在于似乎自己忘掉了这些基础(^^囧^^)。不过意识到问题,问题就好解决了,就如这个问题一样,找到问题关键,解决便轻而易举。