我当时正在学习C语言中的数据结构,并想实现它,
下面是代码及其给出的奇怪输出,在添加记录函数中显示时显示正确的数据,但是当从main调用同一函数时,值已更改,我知道其与按值调用有关,但无法弄清楚确切的数据原因。

PS:很抱歉,如果程序太长或不符合标准

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

struct record;
typedef struct record data_record;

struct record{
    int data;
    struct record *next_record;
};

// forward function declarations
data_record *get_record();
void initialize_record(data_record *,int);
void display_record(data_record *);
void display_list(data_record *,int);
data_record *generate_link_list(data_record *,int);
void add_record(data_record *,data_record,int);

int main(int argc,char *argv[])
{
    printf("Initializing the data ... \n");
    printf("Data length: %d \n",sizeof(data_record));
    int array_length = 5;

    data_record *start;
    // generate_list function
    start = generate_link_list(start,array_length);
    printf("------------------------------------\n\n");
    display_list(start,array_length);
    printf("Address : %x \n",start);

    // add the extra item to the existing list
    data_record record;
    record.data = 100;
    record.next_record = NULL;
    add_record(start,record,2);
    display_list(start,array_length +1);

    printf("Terminating the program \n");
    return 0;
}

data_record *get_record()
{
    return (data_record *)malloc(sizeof(data_record));
}

void initialize_record(data_record *record,int data)
{
    record->data = data;
    record->next_record = NULL;
}

void display_record(data_record *record)
{
    printf("Printing data: \t");
    printf("Data: %d \t",record->data);
    printf("Next Item address: %x \n",record->next_record);
}

void display_list(data_record *list,int length)
{
    data_record *list_pointer = list;
    printf("Printing the list: \n");
    int index;
    for(index = 0;index < length;index++)
    {
        display_record(list_pointer);
        list_pointer = list_pointer->next_record;
    }
    printf("Done with the printing \n");
}

data_record *generate_link_list(data_record *list,int array_length)
{
    list = get_record();
    initialize_record(list,0);
    data_record *current_record_pointer, *record;
    int index = 0;

    current_record_pointer = list;

    printf("First record: ");
    display_record(current_record_pointer);

    for(index = 1;index < array_length;index ++)
    {
        record = get_record();
        initialize_record(record,index);
        current_record_pointer->next_record = record;
        current_record_pointer = record;
    }
    return list;
}

void add_record(data_record *list,data_record record,int position)
{
    printf("Start address %x \n",list);
    printf("New record address %x \n",&record);
    data_record *list_pointer = list;
    int list_position = 0;
    for(list_position = 0;list_position < position - 1;list_position ++)
    {
        list_pointer = list_pointer->next_record;
    }
    if(list_pointer != NULL)
    {
        data_record *next_record = list_pointer->next_record;
        list_pointer->next_record = &record;
        record.next_record = next_record;
    }
    display_list(list,6);
}


从add函数调用时,display_list显示正确,但是在add函数更改后从main调用时,display_list正确

最佳答案

问题是传递给recordadd_recordrecordmain的副本。当参数是结构时,值传递就是这样工作的。因此,对record所做的更改只会影响副本,而不会影响原始副本。

要解决此问题,请声明record作为指针

void add_record(data_record *list,data_record *record,int position)
{
    ...

    list_pointer->next_record = record;
    record->next_record = next_record;

    ...
}


并在main中传递记录的地址

add_record(start,&record,2);




注意:将start传递给generate_link_list是没有意义的,因为start不包含generate_link_list所需或使用的任何信息。因此将其更改为:

data_record *generate_link_list(int array_length)
{
    data_record *list = get_record();

    ...
}




另一个说明:正如@JonathanLeffler在评论中指出的那样,您应该始终使用get_record函数创建记录。我会更进一步地说get_recordinitialize_record应该合并为单个函数create_record,例如

data_record *create_record(int data)
{
    data_record *record = malloc(sizeof(data_record));
    if ( record )
    {
        record->data = data;
        record->next_record = NULL;
    }
}


然后main中的代码变为

// add the extra item to the existing list
data_record *record = create_record(100);
if (record)
    add_record(start,record,2);
display_list(start,array_length +1);


通过对列表中的所有记录使用create_record,可以在需要时安全地free列表中的项目。

关于c - 链接列表添加功能无法正常工作,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38413836/

10-10 14:06
查看更多