C链表列表和指针

时间:2012-05-13 17:54:27

标签: c pointers reference stack

我是C的新手,我正在尝试使用链表实现堆栈。目前设置Stack,到目前为止一切都很好。当我尝试将新节点推送到列表时,问题就出现了。  我目前有

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()指向的节点上调用topPtr,而topPtr曾经打印过的值(在这种情况下) p')。据我所知,从我所做的狩猎来看,它的外观和感觉都是正确的,我不知道我错过了什么。

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

朝着正确的方向“推”是一个很好的推动......

5 个答案:

答案 0 :(得分:2)

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

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

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

此外,我假设StackNodePtrtypedef的{​​{1}}。我是对的吗? StackNode*这个指针类型有充分的理由吗?通常它只是使事情复杂化。我建议typedef仅在指针类型为真正的不透明类型时(即Windows上的typedef)。

答案 1 :(得分:1)

应该是

  *topPtr = sNP;

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

答案 2 :(得分:0)

你的函数push正在修改指针topPtr。由于C是按值传递的,因此将头作为值传递,并且传递的副本在push中被修改。因此,要修改指针本身,需要将指针传递给指针。此外,需要更正函数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. 
}

答案 3 :(得分:0)

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

不,你没有。您将值分配给指针的本地副本。您更改topPtr本身的值,并且不会超出范围。相反,您应该写入指向的位置:

*topPtr = sNP;

答案 4 :(得分:0)

它看起来像这里的bug: topPtr =&amp; sNP; //刚刚分配了???

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