2010-01-23 3 views
1

Я отправил вопрос несколько дней назад о связанном списке в C. Я думал, что все в порядке, тогда профессор пишет нам, что вместо этой подписи :C Связанный список содержит только первый элемент ... не уверен, что происходит с отдыхом

int insert_intlist(INTLIST* lst, int n); /* Inserts an int (n) into an intlist from the beginning*/ 

Он случайно имел в виду:

int insert_intlist(INTLIST** lst, int n); /* Inserts an int (n) into an intlist from the beginning*/ 

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

Он начинается с давая нам это:

INTLIST* init_intlist(int n) 
{ 
    INTLIST *lst; //pointer to store node 
    lst = (INTLIST *)malloc(sizeof(INTLIST)); //create enough memory for the node 
    lst->datum = n; //set the value 
    lst->next = NULL; //set the pointer 
    return lst; //return the new list 
} 

Что просто инициализировать список как и в основной:

if (lst==NULL) 
        lst = init_intlist(i); 
       else 
        insert_intlist(lst, i); 

LST имеет тип IntList * поэтому его определяется как IntList * местное стандартное время Поэтому я читаю некоторые цифры из текстового файла, такого как 1 3 4 9. Предполагается создать связанный список из этого ... так что первое число будет идти в init_intlist (1); И это было определено выше. Затем он захватывает следующее число 3 в этом случае и вызывает insert_intlist (lst, 3). Ну вот мой insert_intlist и все, что я хочу сделать, это вставить в начале списка:

int insert_intlist(INTLIST** lst, int n) 
{ 
    INTLIST* lstTemp; //pointer to store temporary node to be added to linked list 
    lstTemp = (INTLIST *)malloc(sizeof(INTLIST)); //create enough memory for the node 
    lstTemp->datum = n; //assign the value 

    //check if there is anything in the list, 
    //there should be, but just in case 
    if(*lst == NULL) 
     { 
      *lst=lstTemp; 
      lstTemp->next=NULL; 
     } 
    else 
     { 
      lstTemp->next = *lst; //attach new node to the front 
      *lst = lstTemp; //incoming new node becomes the head of the list 
     } 

    return 0; 
} 

Таким образом, если список содержал 1 первоначально эта функция будет просто создать новый узел, а затем сделать этот темп node-> следующий пункт в голову списка (который, как я думал, был lst), а затем переназначить головку списка на этот новый временный узел.

Все это выглядит, как он работает право, но когда я пытаюсь напечатать мой список на экране он только печатает номер 1.

Кто-нибудь есть какие-либо подсказки относительно того, что я делаю не так?

+4

Не очень полезно, но вы считаете, что удушаете своего профессора? :) – Skurmedel

+1

Без комментариев ... (15 символов) – oJM86o

+1

Я думаю, вы должны дать своему профессору неудачный класс! –

ответ

1

Вам передается указатель на указатель. Вы хотите изменить указатель, на который указывает указатель, а не указатель на сам указатель. Имеет ли это смысл?

if(lst == NULL) 

Здесь вы проверяете, был ли у вас указатель NULL. Хорошая практика для проверки ошибок, но не для того, что вы делали прямо там. Если lst NULL, то у вас даже нет указателя на указатель, он ничего не может сделать и должен возвращать ненулевой код ошибки, не делая ничего другого.

Как только вы уверены, что ваш указатель не равен NULL, затем вы смотрите на указатель, указывающий на (*lst). Указанный указатель - это указатель на первый элемент списка. Если : указатель NULL, , то вы меняете его на указатель нового элемента. В основном, где вы используете lst, вы должны использовать *lst или (*lst). (ПОМНИТЕ: оператор * бежит после-> оператор!Таким образом, чтобы получить поле в объекте, на которое указывает указатель, на который указывает lst [pant, pant], вы используете (*lst)->whatever.)

P.S. Этот вид работы указателя критический, чтобы научиться быть хорошим программистом, особенно с C.

P.P.S. Другая вещь, которую вы ошибались в том, что вместо

insert_intlist(lst, i); 

вы должны назвать его как

insert_intlist(&lst, i); 

... и для точек домовых, проверить код возврата ошибок.

+0

Может кто-нибудь объяснить мне, почему и почему я знаю и является адресом ... но серьезно этот класс просто очень сложный, это было наше ПЕРВОЕ НАЗНАЧЕНИЕ и я должен был изучить C в основном самостоятельно. – oJM86o

+0

'& lst', потому что то, что вы передаете, является указателем на указатель на список, а' lst' - только указатель на список. Обратите внимание, что «указатель на» является синонимом «адреса». –

+0

Может ли кто-нибудь порекомендовать хорошую книгу, этот материал действительно сложно, я не могу поверить, что получаю это далеко .... – oJM86o

0

Первая проблема, которая возникает у меня в голове, заключается в том, что в insert_intlist() вы делаете lst = lstTemp;. Это должно быть *lst = lstTemp;. Таким образом, вы назначаете указатель списка, который вы поставили, а не указатель указателя списка (который ничего не обновляет вне функции).

+0

Я попробовал, чтобы увидеть мою отредактированную часть. – oJM86o

0

Поскольку вы используете указатель на другой указатель в функции вставки, вы можете изменить, в какой ячейке памяти последний фактически указывает на. Я изменил код вставить немного, и она отлично работает:

int insert_intlist(INTLIST** lst, int n) 
{ 
    INTLIST* lstTemp; //pointer to store temporary node to be added to linked list 
    lstTemp = (INTLIST *)malloc(sizeof(INTLIST)); //create enough memory for the node 
    lstTemp->datum = n; //assign the value 

    //check if there is anything in the list, 
    //there should be, but just in case 
    if(*lst == NULL) 
    { 
     lstTemp->next=NULL; 
     *lst = lstTemp; 
    } 
    else 
    { 
     lstTemp->next = *lst; //attach new node to the front 
     *lst = lstTemp; //incoming new node becomes the head of the list 
    } 

return 0; 

}

EDIT: Я вижу, вы редактировали Ваш вопрос. В этом случае, возможно, вы вызываете функцию вставки неправильно в main(). Попробуйте

int main() 
{ 
    INTLIST *head; 
    head = init_intlist(42); 
    insert_intlist(&head, 41); 
    display(head); 
    return 0; 
} 
+0

У меня есть то же самое, но в основном, когда я пытаюсь распечатать список, он отображает только один элемент. – oJM86o

+0

как вы печатаете список? –

+0

Если это помогает, я разместил здесь весь код: http://dpaste.de/ZDKt/ Я могу проверить, работает ли он отлично. Может быть, что-то не так с функцией, которую вы используете для прохождения связанного списка? – user108127

0

Проверьте, чтобы увидеть, если lstTemp-> следующая == NULL после lstTemp-> следующая = LST;