[英]Binary trees and passing arguments
I have a binary tree program in C++ ,which parses a string of characters and then forms a binary tree depending on it.I have a problem with transmitting parameters to my functions . 我有一个用C ++编写的二叉树程序,该程序解析一个字符串,然后根据它构成一个二叉树。我在向函数传递参数时遇到问题。 I tried reading tutorial on passing arguments to functions in c ,and changed my code ,but it doesn't seem to work.I would like someone to help me fix the passing of arguments. 我尝试阅读有关在c语言中将参数传递给函数的教程,并更改了我的代码,但它似乎不起作用。我希望有人帮助我解决参数传递问题。
The header : 标头:
#define NULL 0
struct TreeEl {
char inf;
struct TreeEl * st, * dr;
};
typedef struct TreeEl root;
root* add(root *r, char st[], int &pos, int &n);
root* create(root *r, char st[100], int n);
void visit(root*);
void preorder(root *r, void visit(root*));
void inorder(root *r, void visit(root*));
void postorder(root *r, void visit(root*));
And the code : 和代码:
#include "arbore_binar.h"
#include <stdio.h>
using namespace std;
void visit(root *r)
{
printf("Node %c",r->inf);
}
root* add(root *r, char st[], int &pos, int &n)
{
int done=0;
do
{
pos++;
printf(" procesing character:,%c \n",st[pos]);
switch (st[pos])
{
case '(':
{
add(r->st, st, pos, n);
break;
}
case ')':
{
done=1;
break;
}
case ',':
{
add(r->dr, st, pos, n);
break;
}
case '$':
{
if (st[pos+1]==',')
done=1;
if (st[pos+1]==')')
done=1;
break;
}
default:
{
if ((st[pos]>=65)&&(st[pos]<=90))
{
printf(" Added: ,%c \n" ,st[pos]);
root *p;
p = new root;
p->inf=st[pos];
p->st=NULL;
p->dr=NULL;
r=p;
if (st[pos+1]==',')
done=1;
if (st[pos+1]==')')
done=1;
}
else
printf("Error,unknown character: %d ",st[pos]);
}
}
} while ((done==0)&&(pos<n));
return r;
}
root* create(root *r, char st[100], int n)
{
int pos=-1;
root* nod = add(r, st, pos, n);
return nod;
}
void preorder(root *v, void visit(root*))
{
if (v == NULL)
return;
else {
visit(v);
preorder(v->st, visit);
preorder(v->dr, visit);
}
}
void inorder(root *v, void visit(root*))
{
if (v == NULL) return;
else {
inorder(v->st, visit);
visit(v);
inorder(v->dr, visit);
}
}
void postorder(root *v, void visit(root*))
{
if (v == NULL) return;
else {
postorder(v->st, visit);
postorder(v->dr, visit);
visit(v);
}
}
void print(root* x)
{
printf("%c" , x->inf ," " );
}
int main()
{
//char a[100] = "A(B(J,$),C(X,D(E,F($,Y))))";
//char a[100] = "A(B,C(X,D(E,F($,Y))))";
char a[100] = "A(B(C(M,$),D),E(F(X,$),G($,Y)))";
root *r;
r=NULL;
r=create(r, a, 31);
printf("Preorder traversal:" );
preorder(r, print);
printf("\n");
printf("Inorder traversal: ");
inorder(r, print);
printf("\n");
printf("Postorder traversal: ");
postorder
(r, print); (r,打印); printf("\\n"); 的printf( “\\ n”);
getchar(); 的getchar(); return 0; 返回0;
}
Remember that C passes pointers by value. 请记住,C按值传递指针。 So code like root *p;r=p;
所以像root *p;r=p;
这样的代码 does not modify the value of root that is present outside the function. 不会修改函数外部存在的root值。
In functions where you are going to reassign r
, you might want to pass it as a pointer to pointer, or root **r
. 在要重新分配r
,您可能希望将其作为指向指针的指针或root **r
传递。 You would call such functions as create(&r, a, 31); 您将调用诸如create(&r,a,31);之类的函数。 to pass the address of the pointer variable to the function as a pointer to the r
pointer. 将指针变量的地址作为r
指针的指针传递给r
。
The trouble you are facing is related to the passing of arguments through by-value and by-reference semantics. 您面临的麻烦与通过按值和按引用语义传递参数有关。 In C, all variables are passed by value . 在C语言中, 所有变量都按value传递 。 Pointers are often referred to as being passed "by-reference", but they are not. 指针通常被称为“通过引用”传递,但事实并非如此。 Instead they enable the modification of other values, in a way which is similar to by-reference semantics. 相反,它们使修改其他值的方式类似于按引用语义。
The issue is that you have the add function: 问题是您具有添加功能:
void create(root *r, char st[100], int n);
create
takes a root*
as its first argument. create
以root*
作为第一个参数。 Thus, it can make changes to the memory pointed to by this parameter. 因此,它可以更改此参数指向的内存。 After execution of the function, the memory pointed to by r
may be different, but r
itself will have the same value - that is, the pointer variable r
will always point to the same place. 函数执行后, r
指向的内存可能会不同,但是r
本身将具有相同的值-也就是说,指针变量r
将始终指向相同的位置。
Why is this relevant? 为什么这是相关的? Look at your main
function and note that the initial value of r
is NULL
. 查看您的main
函数,请注意r
的初始值为NULL
。 After passing r
to the create
function, r
must still be NULL
. 将r
传递给create
函数之后, r
必须仍然为 NULL
。 Therefore, you never have a pointer to the tree at all! 因此,您根本没有指向树的指针!
This probably does not seem like the case to you because in the create
function, you assign a value to r
(specifically the line r=p
). 在您看来,这种情况似乎不一样,因为在create
函数中,您为r
分配了一个值(特别是行r=p
)。 Unfortunately, that line only modifies the function-local copy of r
, so the changes are not reflected in main
. 不幸的是,该行仅修改了r
的函数局部副本 ,因此更改未反映在main
。
How could you fix this? 您该如何解决? Instead of trying to modify the main
-local copy of r
within the create
function, you could change the create
function to return root*
instead of void
. 无需尝试在create
函数中修改r
的main
local副本,您可以将create
函数更改为返回root*
而不是void
。 Then, in main
, change your calling of the function to this: 然后,在main
,将对函数的调用更改为:
r = create(r, a, 31);
Provided create
returns a pointer to the root of the tree, you will now be able to maintain a reference to your tree everywhere, and it should work properly with your other functions. 提供的create
将返回指向树根的指针,现在您将能够在任何地方维护对树的引用,并且该树应该与您的其他功能一起正常工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.