当前位置:   article > 正文

指针引用传参和指针传参,实参与形参,无法将参数从int*转换为int*&_“int ip_fixed_op(double &,const int &,const int &)

“int ip_fixed_op(double &,const int &,const int &)”: 无法将参数 1 从“cons

通过本文探究指针引用传参和指针传参的差异,以及引用的特性。

最近有位同学找到我,说他在学习树的过程中遇到一个问题,冥思苦想了几个小时都不得解。

这个问题是这样的,他通过广义表创建一棵树,再遍历输出时却得到的是空值。先序遍历的函数经过测试没有问题,广义表表示也没问题,那问题肯定就在建树环节。

他的建树代码段是这样的:(还没学到树的可以跳到后面)

主函数:

  1. int main()
  2. {
  3. BinaryTree<char> T;
  4. const char array[] = "A(B,C)";
  5. T.CreateBinTree(T.getRoot(), array);
  6. T.PreOrderTraverse(T.getRoot());
  7. return 0;
  8. }

获取根结点:

BinTreeNode<T>* getRoot() { return root; }

建树:

  1. template<class T>
  2. void BinaryTree<T>::CreateBinTree(BinTreeNode<T>* root,const char* array) {
  3. LinkStack< BinTreeNode<T>*> stack;
  4. BinTreeNode<T>* p ,*t;
  5. root = NULL;
  6. int k=0;//k=1左子树 k=2右子树
  7. int i = 0;
  8. while (array[i]) {
  9. switch (array[i]) {
  10. case ' ':
  11. break;
  12. case '(': {
  13. stack.Push(p);
  14. k = 1;
  15. break;
  16. }
  17. case ',': {
  18. k = 2;
  19. break;
  20. }
  21. case ')': {
  22. stack.Pop(t);
  23. break;
  24. }
  25. default:
  26. p = new BinTreeNode<T>(array[i]);
  27. if (root == NULL)root = p;
  28. else {
  29. if (k == 1) {
  30. t=stack.getTop();
  31. t->lchild = p;
  32. }
  33. else {
  34. t=stack.getTop();
  35. t->rchild = p;
  36. }
  37. }
  38. }
  39. i++;
  40. }
  41. }

 总的来说就是传入树根,根据广义表的字符串如"A(B,C)"来建树

 看起来建树的过程没有什么问题,但是分别在建树函数体中和主函数中输出一次root的值,却得到了这样的结果:

不会树的同学看这里,这个问题简单说就是传入指针root,在函数中对root进行操作,但并没有改变实际参数root。

这其实是部分初学者的一个误解,认为传入指针就能一定修改与该指针相关的变量的值,实际上向函数传入指针,指针形参和实参有同个值(变量地址),所以能通过地址对所指变量进行修改,但它们本身仍遵循函数参数传递的规则,即函数内的指针形参改变了值(形参指针指向了另一个变量),实参指针的值(指向)不会改变。

建树的函数中

  1. p = new BinTreeNode<T>(array[i]);
  2. if (root == NULL)root = p;

 这两句正是改变了形参的指向,但实参的root指向不变,所以形参建的树没有传到外面。

要使函数内部的形参指针指向改变,实参指针也随之改变,很容易想到指针引用传参,引用是给变量起个别名,函数用到引用传参时,在函数内改变了形参的值,实参也会改变。

将建树函数这样修改:

void BinaryTree<T>::CreateBinTree(BinTreeNode<T>* &root,const char* array)

于是形参便成为了对实参的引用。我以为我行了,一运行,出现这个错误: 

关于题目中的“无法将参数从int*转换为int*&”问题,与这个类似,出现这种情况一般是将一个函数的返回值(非引用返回)作为参数直接传入一个形参为引用变量的函数中。int*和int* &尽管返回的值是相同的,但int*就仅仅只是返回一个值这个值本身没有载体,除非用一个变量去接收它作为载体,而int* &返回一个引用,是有这个值的载体。

 我利用getRoot()函数(开头的代码)会返回一个指针的值(是一个地址值),但这个值无法被引用。这又涉及到一个知识点:

引用要明确指向一个具体的变量,而不能只是一个值。

所以出现这个报错。

将getRoot这样修改:

BinTreeNode<T>* &getRoot() { return root; }

即可返回root指针的引用,是一个具体的变量,于是便能成功在外部获取函数内建的树。

当然,在涉及树的实际开发过程中,并不推荐直接返回树根的引用,这样对于数据来说是不安全的。

最后再附图便于理解:

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/bf789/article/detail/63115
推荐阅读
相关标签
  

闽ICP备14008679号