我自己在写一个递归函数时发现了参数传递的一个小细节,就是形参变量前到底要不要加&(在这里不是取地址运算符,只是引用的一个标示符),亲自实践了一下稍微弄明白了一点什么时候必须要加&,什么时候不能加。如下面这样一段程序:
struct Node{
int num; //储存该节点的值
int sum; //储存从根节点到该节点的值得和
Node* lchild;
Node* rchild;
};
class Tree{
public:
Node* root;
void create(Node* &r,vector<int> &v,int &n){ //递归建树
if (v[n]==-1){
n++;
return;
}
r=new Node;
r->num=v[n++];
r->lchild=r->rchild=NULL;
create(r->lchild,v,n);
create(r->rchild,v,n);
}
Tree(vector<int> &v){
int nn=0;
create(root,v,nn);
}
bool quickSum(Node* &r,int target,int parnum){ //递归检查sum是否达到指定值
if (r==NULL) return 0;
r->sum=r->num+parnum;
parnum=r->sum;
if (r->sum>target) return 0;
if (r->lchild==NULL&&r->rchild==NULL){
if (r->sum==target) return 1;
else return 0;
}
if (quickSum(r->lchild,target,parnum)) return 1;
if (quickSum(r->rchild,target,parnum)) return 1;
return 0;
}
};
在上面这一段代码中,create()函数中的形参(int &n)必须要加&,开始我并没有加,导致了bug出现。因为这是一个递归自己的函数,在进入某一次调用后n应该加1,但是当返回时,n并没有保留加1,换句话说n++的n并不是原函数中的n(不知道说清楚了没有。。)。如果没明白可以看下面这段经典的代码:
#include<stdio.h>
void swap (int a,int b)
{
int t=a;
a=b;
b=t;
}
int main(){
int a=3,b=4;
swap(a,b);
printf("%d %d\n", a, b);
return 0;
}
这个输出结果还是3 4,交换函数根本没有作用,原因就是在函数中交换的a和b根本不是main函数中的a和b,只不过变量名相同罢了,但根本不是一回事。正确的c++写法是这样的:
void swap(int &a,int &b)
{
int temp;
temp=a;
a=b;
b=temp;
}
调用时写swap(a,b)函数直接把a和b的地址作为参数传给swap()。
但在quickSum函数中的int parnum就一定不能加&。因为parnum存的该节点的父节点的sum值,也就是到从根节点到该节点父节点这条路径上的所有节点的num和。在递归一次计算完每个节点的左孩子的sum值返回时,parnum必须还是父节点的值,而不能左孩子的值覆盖掉,从而可以计算右孩子的sum。