链接列表添加功能无法按预期工作

时间:2016-07-16 17:36:35

标签: c linked-list

我正在学习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显示正确但在添加函数后从main调用时值相同

1 个答案:

答案 0 :(得分:2)

问题是传递给record的{​​{1}}是add_recordrecord的副本。当参数是结构时,这就是值传递的工作原理。因此,对main的更改只会影响副本,而不会影响原始副本。

要解决此问题,请将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

另一个注意事项:正如@JonathanLeffler在评论中指出的那样,您应该始终使用data_record *generate_link_list(int array_length) { data_record *list = get_record(); ... } 函数来创建记录。我会更进一步说,get_recordget_record应合并为一个函数initialize_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列表中的项目。