0

文字列を解析し、それに応じてバイナリ ツリーを形成する C++ のバイナリ ツリー プログラムがあります。関数へのパラメータの送信に問題があります。C で関数に引数を渡す方法に関するチュートリアルを読んで、コードを変更しましたが、うまくいかないようです。誰かに引数の受け渡しを修正してもらいたいです。

ヘッダー:

     #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*));

そしてコード:

    #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、印刷); printf("\n");

getchar(); 0 を返します。

}
4

2 に答える 2

2

C はポインターを値で渡すことに注意してください。したがって、コード likeroot *p;r=p;は、関数の外にある root の値を変更しません。

を再代入する関数ではr、ポインタへのポインタとして渡すか、またはroot **r. create(&r, a, 31); などの関数を呼び出します。ポインター変数のアドレスをポインターへのrポインターとして関数に渡します。

于 2013-01-13T16:47:24.810 に答える
2

あなたが直面している問題は、値渡しおよび参照渡しのセマンティクスによる引数の受け渡しに関連しています。C では、すべての変数が値によって渡されます。ポインターは「参照渡し」で渡されるとよく​​言われますが、そうではありません。代わりに、参照セマンティクスに似た方法で、他の値の変更を可能にします。

問題は、追加機能があることです:

void create(root *r, char st[100], int n);

createroot*最初の引数としてaを取ります。したがって、このパラメータが指すメモリに変更を加えることができます。関数の実行後、 が指すメモリはr異なる場合がありますが、rそれ自体は同じ値になります。つまり、ポインター変数rは常に同じ場所を指します。

なぜこれが関連するのですか?関数を見mainて、 の初期値が であることに注意してrくださいNULL。関数に渡しrた後も、 . したがって、ツリーへのポインターはまったくありません。creater NULL

create関数では値をr(具体的には lineに) 代入するため、これはおそらく当てはまらないと思われますr=p。残念ながら、その行は の関数ローカル コピーを変更するだけなrので、変更は に反映されませんmain

どうすればこれを修正できますか? 関数内のmain-local コピーを変更しようとする代わりに、関数をの代わりに返すように変更できます。次に、 で、関数の呼び出しを次のように変更します。rcreatecreateroot*voidmain

r = create(r, a, 31);

ツリーのルートへのポインターcreateを返す場合、どこでもツリーへの参照を維持できるようになり、他の関数で適切に動作するはずです。

于 2013-01-13T16:48:04.187 に答える