在链表末尾插入

Insert at the end of the linked list

编辑
谢谢大家,我现在明白我是按价值传递的。但是现在我对此有另一个疑问。
在这里,append 函数的任务涉及更改结束指针。
append 函数的两个参数都是指针的,在第一种情况下,第一个参数是 &pt1,第二个参数是 &pt2。
该函数制作了具有结构点类型的结束指针的副本。 由于传递了 &pt1,因此这个重复的结束指针的 x 分量为 1,y 分量为 -1,下一个分量为 NULL。 现在我们将此副本的下一个组件更改为 newpt 指针和 return newpt 指针。

回到主要功能, 原来的结束指针现在的值为 &pt2。
按照我的理解, 结束->下一个= newpt;不应该对 main 中的原始结束指针产生任何变化。
那么为什么我会得到一个喜欢的列表。 这是代码:

struct point{
    int x;
    int y;
    struct point *next;
};
void printPoints(struct point *);
void printPoint(struct point *);
struct point * append(struct point *, struct point *);
void main(){
    struct point pt1={1,-1,NULL};
    struct point pt2={2,-2,NULL};
    struct point pt3={3,-3,NULL};
    struct point *start, *end;
    start=end=&pt1;
    end=append(end,&pt2);
    end=append(end,&pt3);
    printPoints(start);
}
void printPoint(struct point *ptr){
    printf("(%d, %d)\n", ptr->x, ptr->y);
}
struct point * append(struct point *end, struct point *newpt){
    end->next=newpt;
    return newpt;
}
void printPoints(struct point *start){
    while(start!=NULL){
        printPoint(start);
        start=start->next;
    }
}

我得到的:
(1, -1)
(2, -2)
(3, -3)

我认为我应该得到的:
(1, -1)


原题
我有一个简单的程序,可以使用函数调用在链表的末尾插入元素。
我的代码:
struct Date{
    int data;
    struct Date *next;
};
void print(struct Date *date_head);
void add(int date, struct Date *date_head);

int main(){
    struct Date *date_head=NULL;
    add(12,date_head);
    add(15,date_head);
}
void print(struct Date *date_head){
    struct Date *ptr=date_head;
    printf("Dates: ");
    while(ptr!=NULL){
        printf("%d ",ptr->data);
        ptr=ptr->next;
    }
    printf("\n");
}
void add(int date, struct Date *date_head){
    //newDate
    struct Date *newDate;
    newDate = (struct Date *)malloc(sizeof(struct Date));
    newDate->data=date;
    newDate->next=NULL;

    //inserting newDate at end
    struct Date *date_ptr;
    date_ptr=date_head;
    if (date_ptr==NULL) {date_head=newDate;}
    else{
        while(date_ptr->next!=NULL){
            date_ptr=date_ptr->next;
        }
        date_ptr->next=newDate;
    }
    print(date_head);
}

我想要的:
日期:12
日期:12 15

我得到的:
日期:12
日期:15

该结构在 add 函数之外变为 NULL。即使我使用指针。为什么? 我不知道我是否犯了初学者错误。

至少把函数的参数交换一下比较好

void add( struct Date *date_head, int date );

该函数按值接受指向在 main 中声明的头节点的指针。即函数处理指针值的副本。在函数内更改副本确实会反映在原始指针上。

函数内的内存分配也可能失败。您应该向函数的调用者报告这种情况。

所以函数应该return一个整数来表示新节点的分配是否成功并且它应该通过引用接受指向头节点的指针。

考虑到所有这些因素,函数声明和定义将如下所示。

int add( struct Date **date_head, int date )
{
    struct Date *newDate = malloc( sizeof( struct Date ) );
    int success = newDate != NULL;

    if ( success )
    {
        newDate->data = date;
        newDate->next = NULL;

        while ( *date_head != NULL ) date_head = &( *date_head )->next;

        *date_head = newDate;
    }

    return success;
}

在 main 中你应该写

struct Date *date_head=NULL;
add( &date_head, 12 );
add( &date_head, 15 );

函数的参数也应该有限定符 const 因为列表不会在函数内改变。

void print( const struct Date *date_head );

如果您想将新节点附加到列表的尾部,那么最好声明一个 twp-sided singly-linked 列表。

您正在将 date_head 指针的值传递给 add 函数,因此 add 函数将拥有该指针的另一个副本,即使您在 add 函数中更改此指针的值并设置它到某个地址号,它不会影响你在 main 中创建的 date_head,所以它总是空的,你可以做的是通过地址传递它:

int main(){
    struct Date *date_head=NULL;
    add(12,&date_head);
    add(15,&date_head);
}

并将添加函数编辑为如下所示:

void add(int date, struct Date **date_head){
    //newDate
    struct Date *newDate;
    newDate = (struct Date *)malloc(sizeof(struct Date));
    newDate->data=date;
    newDate->next=NULL;

    //inserting newDate at end
    struct Date *date_ptr;
    date_ptr=*date_head;
    if (date_ptr==NULL) {*date_head= newDate;}
    else{
        while(date_ptr->next!=NULL){
            date_ptr=date_ptr->next;
        }
        date_ptr->next=newDate;
    }
    print(*date_head);
}