递归调用时的参数写法之引用&

来源:互联网 发布:软件开发技术发展方向 编辑:程序博客网 时间:2024/05/17 22:06

我自己在写一个递归函数时发现了参数传递的一个小细节,就是形参变量前到底要不要加&(在这里不是取地址运算符,只是引用的一个标示符),亲自实践了一下稍微弄明白了一点什么时候必须要加&,什么时候不能加。如下面这样一段程序:

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。