EDIT
谢谢大家,我现在明白我在传递价值。但现在我对此有另一个疑问。
这里,append函数的任务涉及更改结束指针。
append函数的两个参数都是指针的,在第一种情况下,第一个参数是&pt1和第二个参数是&pt2。
函数生成具有结构点类型的结束指针的副本。由于&传递pt1,那么这个重复的结束指针的x分量为1,y分量为-1,下一个分量为NULL。现在,我们将此副本的下一个组件更改为newpt指针,并返回newpt指针。
回到主函数,原来的结束指针现在的值为&pt2。
据我所知,end->next=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(
原始问题
我有一个简单的程序,可以使用函数调用在链表的末尾插入元素
我的代码:
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
数据:1215
我得到的:
日期:12
时间:15
在add函数外,结构变为NULL。即使我在使用指针。为什么?我不知道我是不是犯了一个初学者的错误。
最好至少交换等函数的参数
void add( struct Date *date_head, int date );
函数接受指向main中通过值声明的头节点的指针。这是一个处理指针值副本的函数。在函数中更改副本确实会反映原始指针。
函数中的内存分配也可能失败。您应该向函数的调用方报告这种情况。
因此,函数应该返回一个整数,说明新节点的分配是否成功,并且它应该通过引用接受指向头节点的指针,即通过指向它的指针。
考虑到所有这些,函数声明和定义将如下所示。
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单链列表。
您将date_head指针的值传递给add函数,因此add函数将有该指针的另一个副本,即使您在add函数中更改该指针的值并将其设置为某个地址号,它也不会影响您在main中创建的date_head,因此它将始终为null,你可以做的是通过地址传递:
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);
}