Практика связанных списков - PullRequest
0 голосов
/ 18 февраля 2020

Итак, в последнее время мы узнали о списках в классе, и я хотел попрактиковаться в них. Программа не запускается. Не удалось заполнить узлы? У меня слишком кружится голова, чтобы сосредоточиться на поиске недостающего ключа. Извините за публикацию такой мелочи!

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

typedef struct node{
    int val;
    struct node *next;
}node_t;


node_t* create_node(int value,node_t *nextnode) {
    node_t *newnode=(node_t*)malloc(sizeof(node_t));
    if(newnode==NULL) {
        printf("ERROR ALLOCATING");
        exit(0);
    }
    newnode->val=value;
    newnode->next=nextnode;
    return newnode;
}

void fill_list(node_t *head) {
    int i=1;
    node_t *current;
    for(;i<21;i++) {
        current=create_node(i,head);
        head=current;
    }
}

void print_list(node_t *head) {
    node_t *current=head;
    while(current) {
        printf("%d",current->val);
        current=current->next;
    }
}


int main() {
    node_t *head=NULL;
    fill_list(head);
    print_list(head);
    return 0;
}

Ответы [ 3 ]

3 голосов
/ 18 февраля 2020

Ваша проблема в том, что fill_list никогда не возвращает новую голову. Таким образом, head в main остается NULL.

Простой способ изменить это поведение состоит в том, чтобы fill_list вернул новую голову:

node_t* fill_list(node_t *head) {
    int i=1;
    node_t *current;
    for(;i<21;i++) {
        current=create_node(i,head);
        head=current;
    }
    return head;
}
1 голос
/ 18 февраля 2020

Проблема

Аргументы функции в C являются «передачей по значению». Проблема в том, что ваша fill_list функция принимает указатель на node_t с именем head, но любые изменения, которые вы вносите в этот указатель, будут не влиять на значение head вне функция. head внутри функции - это совсем не то, что head в вашем main().

Быстрое исправление

Если вы действительно хотите изменить значение из head (тот, что находится вне функции), то вы должны передать функции указатель на бит памяти, в котором находится head. Для вашего примера это означает указатель на указатель на node_t.

Так что ваш fill_list будет выглядеть так:

void fill_list(node_t **head) {
    int i=1;
    node_t *current;
    for(;i<21;i++) {
        current=create_node(i, *head);
        *head=current;
    }
}

Обратите внимание, что теперь вы должны разыменовать указатель перед передавая его create_node.

Разыменовывая в назначении *head = current, вы устанавливаете содержимое памяти, на которое указывает head. Это та же самая память, в которой хранится переменная head, объявленная в вашем main(). Это то, что вы хотите.

Теперь вы можете позвонить fill_list следующим образом:

fill_list(&head)

Better Fix

1048 * верните указатель на голову, например:

node_t* fill_list() {
    int i=1;
    node_t *head = NULL;
    node_t *current;
    for(;i<21;i++) {
        current=create_node(i, head);
        head=current;
    }

    return head;
}

, а затем main():

int main() {
    node_t *head = fill_list();
    print_list(head);
    return 0;
}
1 голос
/ 18 февраля 2020

Внутри функции fill_list изменяется параметр head.

void fill_list(node_t *head) {
    int i=1;
    node_t *current;
    for(;i<21;i++) {
        current=create_node(i,head);
        head=current;
    }
}

Но функция имеет дело с копией аргумента, переданного функции. Таким образом, исходная головка указателя, определенная в main, ничего не знает об этих изменениях.

Вы должны вернуть значение заголовка параметра функции из функции и присвоить его указателю, определенному в main.

Таким образом, функция может выглядеть как

node_t * fill_list(node_t *head) {
    for( int i = 1; i < 21; i++ ) 
    {
        head = create_node( i, head );
    }

    return head;
}

и в main должно быть

node_t *head = NULL;
head = fill_list( head );

Другой способ - передать указатель на функцию fill_list по ссылке. В этом случае функция может выглядеть

void fill_list( node_t **head ) {
    for ( int i = 1; i < 21; i++ ) {
        *head = create_node( i, *head );
    }
}

И в основном вы должны написать

node_t *head = NULL;
fill_list( &head );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...