为什么通过引用传递修复了我的递归错误?

时间:2014-11-11 20:39:20

标签: c++ recursion vector

我刚开始学习递归,我有一个程序可以搜索5个int的向量作为值,并返回值的下标位置。我注意到当我按值传递向量时,我得到一个不正确的下标位置,如72784658.

但是,当我通过引用传递向量时,不做其他更改,我得到了正确的答案。有人可以解释原因吗?下面是按值传递向量的代码,它会产生错误的答案。

#include <vector>
#include <iostream>
using namespace std;

int search( vector<int>, int, int );

int main() 
{
    vector<int> myInts;
    for( int i = 0; i < 5; i++ )
        myInts.push_back( i );

    cout << "The number 2 is at subsript " << search( myInts, 2, 0 ) << endl;

    return 0; 
}

int search( vector<int> vec, int val, int index )
{
    if( index < vec.size() )
    {
        if( vec[index] == val )
            return index;
        else
            search( vec, val, index + 1 );
    }
    else
        return -1;
}

1 个答案:

答案 0 :(得分:5)

你递归,但不要返回递归调用的值:

search( vec, val, index + 1 );
// Should be this:
return search( vec, val, index + 1 );

这导致在不返回任何特定值的情况下到达函数的结尾,因此任何结果都是可能的,包括没有结果。在没有遇到return语句的情况下到达非void函数末尾的流是未定义的行为,因此编译器在此时使程序崩溃是合法的。

vec更改为引用可能会导致index参数占用不同的CPU寄存器,可能是用于将值返回给调用者的CPU寄存器。这可以解释为什么当您将vec更改为引用时它似乎有效,但升级编译器,更改编译器选项或使用不同的编译器可能会产生完全不同的结果。所以,即使它按照你想要的方式工作,也只是一个幸运的巧合。

作为旁注,请始终在启用所有可能警告的情况下进行编译,并且我还建议发出所有警告错误(-Wall -pedantic)。使用这些选项,此代码甚至无法编译。