1

我是 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'

它似乎在推送中工作正常,但是我调用了指向printf()的节点,而以前打印出来的值(在本例中为“p”)。据我从狩猎中得知,它看起来和感觉都是正确的,我不知道我错过了什么。topPtrtopPtr

可能是我做过的地方topPtr = &sNP;吗?

任何朝着正确方向的“推动”都是好的推动……

4

5 回答 5

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

此分配在函数外部不可见。 topPtr是按值传递的,即复制它并传递给函数。因此,分配不同的值只会修改副本;原始参数仍然指向旧的内存位置。

如果您需要以这种方式修改参数,则需要另一个间接级别,即采用StackNodePtr**.

另外,我假设这StackNodePtr是 a typedeffor a StackNode*。我说得对吗?typedef这种指针类型有充分的理由吗?通常它只会使事情复杂化。我建议typedef仅当指针类型确实是不透明类型(即HANDLEWindows 上的 a )时才使用指针类型。

于 2012-05-13T18:00:07.240 回答
1

它应该是

  *topPtr = sNP;

这样,调用者将指针传递到的原始头,即成为新头的下一个头,被正确“覆盖”,并且调用者具有指向新头的正确指针。

于 2012-05-13T18:00:15.433 回答
0

您的函数 push 正在修改指针 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. 
}
于 2012-05-13T17:59:31.657 回答
0
topPtr = &sNP;      // Just assigned it???

不,你没有。您将值分配给指针的本地副本。你改变了topPtr它本身的价值,它是不会走出去的。相反,您应该写入它指向的位置:

*topPtr = sNP;
于 2012-05-13T18:00:02.520 回答
0

它看起来像错误在这里:topPtr = &sNP; // 刚刚赋值???

而不是 push 返回 void。更改它以返回堆栈的新头部。返回sNp;

于 2012-05-13T18:02:18.467 回答