2013-11-17 3 views
0

Я пытаюсь понять так называемый связанный список в c с помощью struct-nodes. Я хочу использовать один и тот же указатель через код, но при выполнении этого цикла for цикл печатает последний символ. Думаю, я понимаю, почему - вероятно, потому, что указатель указывает на второй и последний узел в программе.Использование того же указателя в связанном списке

Программа помещает два символа в последовательные узлы - буквы «h» и «e». И цель состоит в том, чтобы напечатать эти символы.

Итак, вопрос: как мне вернуться к первому узлу с помощью этого указателя? Единственный ответ для создания двух указателей - то есть одного указателя, называемого, например, startpointer и другого указателя, называемого nextpointer? Или я могу каким-то образом использовать один и тот же указатель, чтобы получить код?

спасибо!

#include <stdio.h> 
#include <stdlib.h> 

struct listNode { 
    char c[2]; 
    struct listNode *ptrNextNode; 
}; 

typedef struct listNode ListNode; 
typedef ListNode *ListNodePtr; 


int main(void) { 

    ListNode list_node; 

    ListNodePtr list_node_ptr; 

    list_node_ptr = malloc(sizeof(list_node)); 

    strcpy(list_node_ptr->c, "h"); 

    list_node_ptr = list_node_ptr->ptrNextNode; 

    list_node_ptr = malloc(sizeof(list_node)); 

    strcpy(list_node_ptr->c, "e"); 

    int i; 
    for (i = 0; i < 2; i++) { 
    printf("%s", list_node_ptr->c); 
    } 

return EXIT_SUCCESS; 
} 
+0

Вы хотите просмотреть список в * обоих направлениях? Или только один? –

+0

Я думаю в одном направлении. Мне нужно создать программу, которая реализует FIFO. Это всего лишь тестовый код для изучения итерации через узлы. – user2991252

ответ

2

Дорога к темной стороне приходит с этим заданием:

list_node_ptr = list_node_ptr->ptrNextNode; 

Здесь вы перезаписать исходный указатель с неинициализированным значением. Это заставляет вас потерять оригинал list_node_ptr, вызывающий утечку памяти. И если вы после вышеупомянутого задания попытались использовать list_node_ptr, кроме как получателя для назначения, это было бы неопределенным поведением.

Хотя в следующей строке вы снова переписываете указатель , что делает его снова действительным указателем и избегает неопределенного поведения.

В общем, вы не делаете связанный список по коду в вопросе. Вы могли сделать что-то вроде

ListNodePtr head, list_node_ptr; 

head = list_node_ptr = calloc(1, sizeof(*list_node_ptr)); 
list_node_ptr->c[0] = 'c'; 
list_node_ptr->next = calloc(1, sizeof(*list_node_ptr)); 

list_node_ptr = list_node_ptr->next; 
list_node_ptr->c[0] = 'e'; 

for (list_node_ptr = head; list_node_ptr != NULL; list_node_ptr = list_node_ptr->next) 
    printf("%s\n", list_node_ptr->c); 

В приведенном выше коде, я выделить next указатель перед тем переназначение его list_node_ptr. Я также сохраняю исходный заголовок списка в переменной head, чтобы вы могли перебирать список.

+1

Это реализация обычного связанного списка, в котором вы можете перемещать узлы только в одном направлении. Если @ user2991252 хочет «вернуться» к узлу на головной узел, должен быть реализован двойной список ссылок – Lihini

+0

@Joachim Pileborg - Спасибо !!! Но я думаю, что вы должны изменить первую строку в ListNodePtr head, list_node_ptr, поскольку ListNodePtr уже вводится в качестве указателя. То есть - нет * необходимо – user2991252

+0

@ user2991252 Вы правы, изменились. Вот почему я лично никогда не создаю псевдонимы для типов указателей, поэтому мне не нужно это помнить. :) –

0

Да, вам нужен двойной список, который должен использовать другой указатель для указания на предыдущий узел.

Смежные вопросы