2012-05-13 6 views
1

私はCの新機能であり、リンクリストを持つスタックを実装しようとしています。現在スタックをセットアップしています。新しいノードをリストにプッシュしようとすると、問題が発生しています。 main()Cリンクリストスタックとポインタ

push()がによって呼び出され 私は現在いる:

push(&(s.head), 'r'); 

機能pushです:

void push(StackNodePtr *topPtr, char value){ 
    printf("topPtr value %c", (*topPtr)->data); // - Is currently 'p' 

    StackNodePtr sNP; 
    sNP = malloc(Node_Size); 
    sNP->data = value;       // - Is currently 'r' 
    sNP->nextPtr = *topPtr; 

    printf("\nsNP value - %c", sNP->nextPtr->data);  // Prints p... cool 
    topPtr = &sNP;  // Just assigned it??? 
    printf("\ntopPtr at end of push = %c", (*topPtr)->data); // prints r... cool 
    // WHY YOU NO REFERENCE sNP LATER!?!? 
} 

一方、バックメインに:

printf("\non the stack...%c", stackTop(s.head)); // prints 'p' 

に思えますプッシュでうまく動作するように、howe ver topPtrが指し示すノードのprintf()と、代わりにtopPtrという値(この場合は 'p')が表示されます。私が行った狩りからわかる限り、それは見た目と正しいことを感じています。私が逃したものは分かりません。

私が行った場所はどこですか?topPtr = &sNP;

右方向に任意の「プッシュ」良いプッシュです...

答えて

0
topPtr = &sNP;  // Just assigned it??? 

いいえ、あなたはしませんでした。ポインタのローカルコピーに値を割り当てました。 topPtr自体の値を変更すると、外に出ることはありません。

*topPtr = sNP; 
0

あなたの機能のプッシュは、ポインタtopPtrを変更しています。 Cは値渡しであるため、先頭は値として渡され、渡されたコピーはプッシュで変更されます。したがって、ポインタ自体を変更するには、ポインタへのポインタを渡す必要があります。また、関数push()のシグネチャを修正してポインタへのポインタを渡す必要があります。最後に、pushのtopPtrの割り当てをコードスニペットに示すように修正する必要があります。

は、以下の変更を行います。

push(&(s.head), 'r'); // pass pointer to pointer, assuming head is pointer, it should be fine 

void push(StackNodePtr **topPtr, char value){ // make first argument pointer to pointer. 

StackNodePtr sNP; 
sNP = malloc(Node_Size); 
sNP->data = value;      
sNP->nextPtr = *topPtr; 

*topPtr = &sNP;  <------*topPtr needs to be assigned. 
} 
2
topPtr = &sNP;  // Just assigned it??? 

この割り当ては、関数の外に表示されていない。その代わりに、あなたはそれが指す場所に書き込む必要があります。 topPtrが値渡しされます。つまり、そのコピーが作成され、関数に渡されます。そのため、異なる値を割り当てることによってのみコピーが変更されます。元の引き数は古いメモリー位置を指しています。

このように引数を変更する必要がある場合は、別のレベルの間接指定が必要です(StackNodePtr**)。

また、私はStackNodePtrStackNode*の場合はtypedefと仮定しています。それについて私は正しいですか? typedefこのポインタタイプには正当な理由はありますか?通常、それは物事を複雑にするだけです。私はtypedef 'が本当に不透明なタイプの場合(つまり、WindowsではHANDLE)、ポインタタイプを推奨します。

+0

はい、あなたはtypedefに関して正しいです、そして、それがうまくいかなかった理由を説明してくれてありがとう。私はそれが可視性と関係があると感じていたが、その原因は不明であった。私がなぜこのようにしているのかについては、私に求められているものですが、今は残りの部分を処理できるはずです。ありがとう! – Tony

1

それはこのよう

*topPtr = sNP; 

する必要があり、オリジナルのヘッドは、呼び出し側は、新しいヘッドの隣になったことへのポインタを通過した正しく「上書き」され、呼び出し側は正しいがあります新しいヘッドへのポインタ。

+1

私はそれを試して、最後の数時間でそれを試して、それはあまりにも肯定的です。ありがとう! – Tony

0

バグのように見えます: topPtr = &sNP; //ちょうどそれを割り当てましたか?

プッシュを返す代わりに、voidを返します。 スタックの新しいヘッドを返すように変更します。 return sNp;