Держите внимание на это:
stack
всегда будет (а) указывает на динамический узел на «вершине» своего стека, или (б) NULL, если стек пуст.
- Когда newely выделен узел STACKSTRUCT должен быть выдвинут, в конце концов
stack
должен указывать на этот узел, но сначала next
указатель, который заново выделенной структуры должна указывать на предыдущую предварительного значения stack
до надстройки (и перейти к stack
).
Мое искусство ascii ужасное, поэтому я не буду беспокоиться.Скорее всего, я подготовил простой пример, который использует свой код, но добавляет print_stack
сбросить текущее состояние стека при добавлении каждого нового узла:
#include <stdio.h>
#include <stdlib.h>
typedef struct _s { // same definition as before
int value;
struct _s *next;
} STACKITEM;
STACKITEM *stack = NULL;
void print_stack()
{
STACKITEM const* item = stack;
for (; item != NULL; item = item->next)
printf("%p : { value=%d; next=%p }\n", item, item->value, item->next);
fputc('\n', stdout);
}
void push_item(int newvalue)
{
STACKITEM *new = malloc(sizeof(STACKITEM));
if(new == NULL) // check for insufficient memory
{
perror("push_item");
exit(EXIT_FAILURE);
}
printf("push.1: stack = %p, new = %p\n", stack, new);
new->value = newvalue;
new->next = stack;
stack = new;
printf("push.2: stack = %p, new->next = %p\n", stack, new->next);
print_stack();
}
int main()
{
for (int i=1; i<=5; ++i)
push_item(i);
}
Примечание: это сознательно просачивается каждый узел. управление памятью не в этом; узел управление есть.
Результат этого будет отличаться от реализации и машины (много значений указателя, которые печатаются). Следуйте значениям указателя, чтобы увидеть, как все эти провода соединяются. Помните, что этот вывод показывает стек в порядке сверху вниз (т. Е. Первый элемент в каждой распечатке является «вершиной» стека). Также обратите внимание, что каждая из этих дампов начинается с узла, на который указывает stack
после нажатие было завершено.
Пример вывода
push.1: stack = 0x0, new = 0x1001054f0
push.2: stack = 0x1001054f0, new->next = 0x0
0x1001054f0 : { value=1; next=0x0 }
push.1: stack = 0x1001054f0, new = 0x100105500
push.2: stack = 0x100105500, new->next = 0x1001054f0
0x100105500 : { value=2; next=0x1001054f0 }
0x1001054f0 : { value=1; next=0x0 }
push.1: stack = 0x100105500, new = 0x100105510
push.2: stack = 0x100105510, new->next = 0x100105500
0x100105510 : { value=3; next=0x100105500 }
0x100105500 : { value=2; next=0x1001054f0 }
0x1001054f0 : { value=1; next=0x0 }
push.1: stack = 0x100105510, new = 0x100105520
push.2: stack = 0x100105520, new->next = 0x100105510
0x100105520 : { value=4; next=0x100105510 }
0x100105510 : { value=3; next=0x100105500 }
0x100105500 : { value=2; next=0x1001054f0 }
0x1001054f0 : { value=1; next=0x0 }
push.1: stack = 0x100105520, new = 0x100200000
push.2: stack = 0x100200000, new->next = 0x100105520
0x100200000 : { value=5; next=0x100105520 }
0x100105520 : { value=4; next=0x100105510 }
0x100105510 : { value=3; next=0x100105500 }
0x100105500 : { value=2; next=0x1001054f0 }
0x1001054f0 : { value=1; next=0x0 }
Обратите внимание, как в каждом конкретном случае, next
указатель новой структуры присваивается текущее значение stack
, то stack
указатель присваивается адрес новой структуры. После завершения структура была «нажата» на стек, и верхний верхний стек отражает это. Кроме того, указатель next
этой структуры теперь предоставляет указатель на верхнюю вершину стека, тем самым обеспечивая цепочку связанных списков, необходимую для структуры данных.
Почему новый будет null? вместо этого вы должны использовать 'stack == NULL', а затем положить stack = new –
Указатель« next »нового узла указывает на текущую вершину стека, а верхняя вершина вершины указывает на новый узел. Подумайте о том, где теперь отображается стек сверху, и как вы доберетесь до вершины * до * стека. – WhozCraig
@WhozCraig пожалуйста, уточните. Кроме того, что вы подразумеваете под «узлом»? Вы имеете в виду структуру? –