递归 带引用参数——看一个大牛的代码的纠结

来源:互联网 发布:洗发水销售数据 编辑:程序博客网 时间:2024/06/14 07:29

一道汉诺塔的题,看大牛的代码写的递归中用到引用参数,甚是神奇。

只找到一些比较简单的关于引用参数的使用问题


代码1

#include <iostream>using namespace std;int   A( int&   n){    if(n == 1)        return   1;    return n*A(n-1);}int   main(){    int   n   =   5;    cout << A(n)<<endl;//求n的阶乘;    return 0;}/**E:\APP\test_Code.cpp||In function 'int A(int&)':|E:\APP\test_Code.cpp|7|error: invalid initialization of non-const reference of type 'int&' from a temporary of type 'int'|E:\APP\test_Code.cpp|3|error: in passing argument 1 of 'int A(int&)'|||=== Build finished: 2 errors, 0 warnings ===|*/

这个代码来自网络,报的错误很明显了,c++primer中也有讲,对于非const的引用形参 必须用严格的同类型的参数来匹配

简单说来

引用是一个变量的别名,
那么这里有一个条件, 被引用的必须是一个变量, 它得有自己的内存空间。
在这个程序中,
n 是变量,
但是 n-1 不是啊,
它是一个值(没有和 n-1 对应的内存空间)
不构成一个独立的变量, 自然无法对它进行引用 ...


代码2,正确的写法

#include <iostream>using namespace std;int   A( int&   n){    if(n == 1)        return   1;    --n;    return (n+1)*A(n);}int   main(){    int   n   =   5;    cout << A(n)<<endl;//求n的阶乘;    return 0;}
每调用一层时先计算n+1,n+1的结果保存在register中,进入下一层递归前编译器会把适当的register的值压栈以便日后恢复,这里某个寄存器就存放着运算的中间结果n+1。日后返回该层时虽然此时n确实是1,但是n+1的结果已经计算过,所以只是从栈顶取出n+1而非重新计算。


进一步思考,代码3

#include <iostream>using namespace std;int   A( int&   n){    if(n == 1)        return   1;    --n;    return A(n)*(n+1);}int   main(){    int   n   =   5;    cout << A(n)<<endl;//输出 16 ;    return 0;}
最后计算的相当于1 * 2 * 2 * 2 * 2 (n的值变为了1)




原创粉丝点击