我可以在主代码中弹出链表的第一个元素(字符),但我不能将那部分代码放在函数中

I can pop the first element (char) of a linked list in the main code, but I cant put that part of the code in a function

我正在处理字符链表,我需要创建一个函数来弹出链表的第一个元素,即:删除第一个节点,释放 space 和 return 第一个节点中保存的字符。

我在程序的主函数中创建了一个完美执行此操作的代码,但是当我将这部分代码放入函数中时,它停止工作,我不明白为什么。

我正在使用 ATmega328p,我的想法是将字符发送到计算机(我使用 minicom 作为终端仿真器)所以函数 USART_Transmit_char() 将一个字符发送到计算机。

主函数中与主函数中的 pop 完美配合的代码是:

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");        
}


节点的结构和推送函数是:

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: 
                      .

(注意下一行打印了 (.))

我不明白为什么当它的相同代码只是在函数中定义时它不起作用。

有人知道为什么会这样吗?我尝试了很多不同的方法来解决这个问题,但结果各不相同。

在函数 pop() 中,您分配 local 参数 string:

string = next_node;

但这里的 string 是一个局部变量,与 main() 中的 string 无关 - 它只是 value 的一个副本main() 中的 string - 或直到您对其进行修改。

您需要额外的间接级别,以便将指针从 main():

传递到 string 对象
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 ) ;