2012-05-13 186 views
1

我是C新手,正在嘗試使用鏈接列表實現堆棧。目前建立的堆棧,迄今爲止都很好。當我嘗試將新節點推入列表時,問題就出現了。 我現在有C鏈接列表堆棧和指針

main()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我在topPtr指向的節點上調用printf(),而topPtr用於打印的值(在本例中爲'p')。據我所知,我從狩獵中得知,它看起來和感覺都很正確,我不知道我錯過了什麼。

難道我在那裏做過topPtr = &sNP;

在正確的方向上沒有任何「推」是一個很好的推動......

回答

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

不,你沒有。您將該值分配給本地指針副本。你自己改變topPtr的值,它不會出去。相反,你應該寫位置它指向:

*topPtr = sNP; 
0

你的功能推入修改該指針topPtr。因爲C是按值傳遞的,所以頭部作爲一個值傳遞並且傳遞的副本在推動中被修改。因此,要修改指針本身,您需要將指針傳遞給指針。此外,函數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**

此外,我假設StackNodePtrtypedefStackNode*。我對嗎? typedef這個指針類型有沒有很好的理由?通常它只是使事情變得複雜。只有當它是真正的不透明類型時(例如Windows上的HANDLE),我纔會推薦typedef'指針類型。

+0

是的,您對typedef是正確的,並感謝您解釋爲什麼它不起作用。我有一種感覺,這與能見度有關,但至於原因是什麼,並不知道。至於我爲什麼這樣做,這正是我所要求的,但現在我應該能夠處理其餘的問題。謝謝! – Tony

1

應該

*topPtr = sNP; 

這樣一來,原來的頭,主叫方已通過指針,這也成爲未來的新掌門人的,是「覆蓋」正確,呼叫者是否具有正確的指向新頭的指針。

+1

我幾乎是積極的,我試圖在最後幾個小時玩它,而且也工作。謝謝! – Tony

0

它看起來像這裏的錯誤: topPtr = &sNP; //剛分配它?

而不是推返回無效。 將其更改爲返回堆棧的新頭部。 return sNp;