Я могу вставить первый элемент (char) связанного списка в основной код, но я не могу поместить эту часть кода в функцию - PullRequest
0 голосов
/ 30 апреля 2019

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

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

Я работаю с ATmega328p, и идея состоит в том, чтобы отправить символы на компьютер (я использую minicom в качестве эмулятора терминала), чтобы функция USART_Transmit_char () отправляла символ на компьютер.

Код восновная функция, которая отлично работает, когда всплывающее окно в главной функции это:

int main(void)
{
        //USART CONFIGURATION
        struct USART_configuration config_57600_8N1 = {57600, 8,1,'n'};
        USART_Init(config_57600_8N1);
        //END USART CONFIGURATION

        //CEATES THE FIRST NODE OF LINKED LIST
        node_char * string = NULL;
        string = malloc(sizeof(node_char));
        string->val = 'H';
        string->next = NULL;

        //ADD ELEMENTS TO LINKED LIST
        push(string,'O');
        push(string,'L');
        push(string,'A');

        //COMMUNICATION WITH COMPUTER
        USART_Transmit_String("I received this line: ");
        USART_Transmit_char(string->val);
        USART_Transmit_char(string->next->val);
        USART_Transmit_char(string->next->next->val);
        USART_Transmit_char(string->next->next->next->val);
        USART_Transmit_String(".\r\n\r\n");

        //HERE I POP THE FIRST ELEMENT
        node_char * next_node = NULL;
        char popped = string->val;
        next_node = string->next;
        free(string);
        string = next_node;
        //HERE THE FIRST ELEMENT HAS BEEN POPPED

        //COMMUNICATION WITH COMPUTER        
        USART_Transmit_String("I popped this char: ");
        USART_Transmit_char(popped);
        USART_Transmit_String(".\r\n\r\n");
        USART_Transmit_String("I am left with this: ");
        USART_Transmit_char(string->val);
        USART_Transmit_char(string->next->val);
        USART_Transmit_char(string->next->next->val);
        USART_Transmit_String(".\r\n\r\n");        
}


Структура узла и функция push:

typedef struct node {
        char val;
        struct node * next;
    } node_char;

void push(node_char * string, char val) {
    node_char * current = string;
    while (current->next != NULL) {
        current = current->next;
    }
    current->next = malloc(sizeof(node_char));
    current->next->val = val;
    current->next->next = NULL;
}

Результат:

I recived this line: HOLA.

I popped this char: H.

I am left whit this: OLA.

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

Новый основной код:

int main(void)
{
        //USART CONFIGURATION
        struct USART_configuration config_57600_8N1 = {57600, 8,1,'n'};
        USART_Init(config_57600_8N1);
        //END USART CONFIGURATION

        //CEATES THE FIRST NODE OF LINKED LIST
        node_char * string = NULL;
        string = malloc(sizeof(node_char));
        string->val = 'H';
        string->next = NULL;

        //ADD ELEMENTS TO LINKED LIST
        push(string,'O');
        push(string,'L');
        push(string,'A');

        //COMMUNICATION WITH COMPUTER
        USART_Transmit_String("I received this line: ");
        USART_Transmit_char(string->val);
        USART_Transmit_char(string->next->val);
        USART_Transmit_char(string->next->next->val);
        USART_Transmit_char(string->next->next->next->val);
        USART_Transmit_String(".\r\n\r\n");

        //HERE I POP THE FIRST ELEMENT

        char popped = pop(string);

        //HERE THE FIRST ELEMENT HAS BEEN POPPED

        //COMMUNICATION WITH COMPUTER
        USART_Transmit_String("I popped this char: ");
        USART_Transmit_char(popped);
        USART_Transmit_String(".\r\n\r\n");
        USART_Transmit_String("I am left with this: ");
        USART_Transmit_char(string->val);
        USART_Transmit_char(string->next->val);
        USART_Transmit_char(string->next->next->val);
        USART_Transmit_String(".\r\n\r\n");        
}

Функция pop определена:

char pop(node_char * string) {
    node_char * next_node = NULL;
    char popped = string->val;
    next_node = string->next;
    free(string);
    string = next_node;
    return popped;
}

Результат:

I recived this line: HOLA.

I popped this char: H.

I am left whit this: 
                      .

(Обратите внимание, что (.)напечатано в следующей строке)

Я не могу понять, почему это не работает, когда тот же код только что определен в функции.

У кого-нибудь есть идея, почему это происходит?Я пробовал много разных способов решения проблемы, с разными результатами, но никогда не достиг желаемого результата.

1 Ответ

1 голос
/ 30 апреля 2019

В функции pop() вы назначаете параметр local string:

string = next_node;

Но здесь string является локальной переменной и не связана с string в main() - это просто копия значения string в main() - или была до Вы изменили его.

Вам необходим дополнительный уровень косвенности, чтобы вы передавали указатель на объект string из main():

char pop(node_char** string) 
{
    node_char* next_node = NULL;
    char popped = (*string)->val;
    next_node = (*string)->next;
    free(*string);
    *string = next_node ;

    return popped;
}

Тогда звоните:

char popped = pop( &string ) ;
...