2016-06-22 11 views
2

Cでスタックを実装しようとしましたが、非常に奇妙なエラーが発生します。何らかの理由で私のプッシュ機能が動作しません。..Cスタックプッシュ機能

typedef struct node 
{ 
    int v; 
    struct node* next; 
}Node; 

void push(Node *stack,int val) 
{ 
    Node *p = (Node *)calloc(1,sizeof(Node)); 
    p->v = val; 
    Node *aux = stack; 
    if(aux == NULL) 
    { 
     stack = p; 
     return; 
    } 
    while(aux->next != NULL) 
     aux = aux->next; 
    aux->next = p; 
} 

を私はNULL

Node *stack = NULL; 

と私のスタックを初期化し、私はこの

push(stack,value) 

L。E.のような関数の何かを呼び出します パラメータdouble pointerを使ってpop関数を作成しようとしましたが、結果はpushと同じです。

void pop(Node **l) 
{ 
    if((*l) == NULL) 
     return; 
    else 
    { 

     Node *aux,*prev; 
     prev = *l; 
     aux = prev->next; 
     if(aux == NULL) 
     { 
      free(prev->v); 
      free(prev); 
      return; 
     } 
     while(aux != NULL) 
     { 
      prev = aux; 
      aux = aux->next; 
     } 
     prev->next = NULL; 
     free(aux->v); 
     free(aux); 
    } 
} 
+0

ですが?実装できる機能を示し実証プログラムであり、それはコンパイルかランタイムエラーですか?あなたの質問を編集し、エラーメッセージを含めてください。 – anatolyg

+3

あなたのスタックはスコープ内で変更されないローカル変数です –

+0

@Costi Ivan私はプッシュとポップがどのようにスタックを探すべきか私の答えで既に示しました。 –

答えて

1

まず政策LIFO(最後の入力第一の出力)を満足するデータ編成です。つまり、新しいデータがスタックの先頭に追加され、スタックの先頭からポップされます。

新しいデータを追加するスタックの末尾を見つけるためにループを追加しないでください。

そして、スタックの先頭を参照渡しする必要があります。関数のパラメータはローカル変数であることを考慮してください。このように、あなたの関数

void push(Node *stack,int val); 

であなたは、関数を終了した後に破棄されます、関数のローカル変数stackを変更しています。元の引数は変更されません。

また、メモリの割り当てに失敗する可能性があります。何らかの方法でエラーを報告する必要があります。ここで

pushpop

#include <stdio.h> 
#include <stdlib.h> 

typedef struct node 
{ 
    int v; 
    struct node *next; 
} Node; 

int push(Node **stack, int val) 
{ 
    Node *p = malloc(sizeof(Node)); 
    int success = p != NULL; 

    if (success) 
    { 
     p->v = val; 
     p->next = *stack; 
     *stack = p; 
    } 

    return success; 
} 

int pop(Node **stack, int *val) 
{ 
    int success = *stack != NULL; 

    if (success) 
    { 
     Node *p = *stack; 
     *stack = (*stack)->next; 
     *val = p->v; 
     free(p); 
    }  

    return success; 
} 

int main(void) 
{ 
    const int N = 10; 
    Node *stack = NULL; 

    int i = 0; 
    int val; 

    while (i < N && push(&stack, i)) i++; 

    while (i != 0 && pop(&stack, &val)) printf("%d ", val); 

    printf("\n"); 

    return 0; 
} 

その出力は、あなたがどのようなエラーを得るのですか

9 8 7 6 5 4 3 2 1 0 
0

あなたは参照することにより、スタック渡す必要があります:プッシュ(&スタック、値)

1

あなたのプッシュ機能は、スタックノードへのポインタを必要とするよう

void push(Node **stack,int val) 
{ 
    Node *p = (Node *)calloc(1,sizeof(Node)); 
    p->v = val; 
    Node *aux = *stack; 
    if(aux == NULL) 
    { 
     *stack = p; 
     return; 
    } 
    while(aux->next != NULL) 
     aux = aux->next; 
    aux->next = p; 
} 

Andcall。

void push(Node **stack, int val) { 
    ... 
    *stack = p; 
    .... 
} 

push(&stack, value); 
+0

ポップアップ機能を確認できますか? –

+0

@CostiIvan test-question:要素を1つ押した後にpop()するとどうなりますか? (それは空でなければなりませんが、あなたの関数を見ると、そうは思わないでしょう)printStack(スタック)関数を書くべきです –

+0

私のやり方は何ですか? –

0

スタックはプッシュ機能に渡されるポインタであるため、関数内のポインタ値の変更は外部反射されません(P->次)

NULLに次のフィールドを初期化することを忘れないでください関数の

Ie:プッシュ関数でstack = somethingを設定した場合、関数外のスタックポインタはそれに設定されません。

push(&stack, 10); 

それとも、簡単に:

それを回避する方法は、あなたは、ポインタ値を変更することができ、ポインタへのポインタとしてスタックを渡すのいずれかである)

void push(Node **stack,int val) 
{ 
    Node *p = (Node *)calloc(1,sizeof(Node)); 
    p->v = val; 
    p->next = NULL; 
    Node *aux = *stack; 
    if(aux == NULL) 
    { 
     *stack = p; 
     return; 
    } 
    while(aux->next != NULL) 
    aux = aux->next; 
    aux->next = p; 
} 

は経由して、それを呼び出します初心者のために、push関数からスタック値を返します。

Node * push(Node *stack,int val) 
{ 
    Node *p = (Node *)calloc(1,sizeof(Node)); 
    p->v = val; 
    p->next = NULL; 
    Node *aux = stack; 
    if(aux == NULL) 
    { 
    stack = p; 
    return stack; 
    } 
    while(aux->next != NULL) 
    aux = aux->next; 
    aux->next = p; 

    return stack; 
} 

コール経由:すべてのスタックの

stack = push(stack, 10); 
+0

'calloc'はゼロに初期化されます。明示的に 'p-> next'をNULLに初期化する必要はありません。 – harper