2012-05-13 2 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' 

보인다 푸시에서 잘 작동하려면, 하우 ver 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**).

또한 StackNodePtrStackNode* 인 경우 typedef이라고 가정합니다. 그것에 대해 내가 맞습니까? 이 포인터 유형 typedef에 대한 좋은 이유가 있습니까? 일반적으로 그것은 단지 사물을 복잡하게합니다. 실제로는 불투명 한 유형 인 경우에만 typedef을 포인터 유형으로 지정하는 것이 좋습니다 (즉, Windows에서는 HANDLE).

+0

네, typedef에 대한 권리가 있으며 작동하지 않는 이유를 설명해 주셔서 감사합니다. 나는 그것이 시야와 관련이 있다고 느꼈지만 원인이 무엇인지는 알 수 없었다. 제가 왜 이렇게하고 있는지에 관해서는, 저에게 요청 된 것이지요. 그러나 이제 나는 그것의 나머지 부분을 다룰 수 있어야합니다. 감사! – Tony

1

그것은 호출자가 새 머리의 다음되었다 포인터를 통과

*topPtr = sNP; 

이런 식으로, 원래 머리,해야한다, "덮어 쓰기"제대로, 그리고 호출자는 올바른있다 새 머리를 가리키는 포인터.

+1

나는 거의 긍정적 인 입장이다. 나는 그걸 가지고 노는 지난 몇 시간 동안 그것을 시도했다. 감사! – Tony

0

버그가있는 것처럼 보입니다. topPtr = &sNP; // 그냥 지정 했습니까 ???

대신 void를 반환합니다. 스택의 새 헤드를 반환하려면이를 변경하십시오. return sNp;