一道汉诺塔的题,看大牛的代码写的递归中用到引用参数,甚是神奇。
只找到一些比较简单的关于引用参数的使用问题
代码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)