[英]Creating a singly-linked list
我有一个 function 来加入两个结构来创建一个链表。
这里,是代码:
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;
}
}
在这里,append 函数的任务涉及更改结束指针。
append function 的 arguments 都是指针; 在第一种情况下,第一个参数是&pt1
,第二个参数是&pt2
。
function 复制了类型为struct point
的结束指针。 由于传递了&pt1
,因此这个重复的结束指针的 x 分量为 1,y 分量为 -1,下一个分量为 NULL。 现在我们将此副本的下一个组件更改为newpt
指针并返回newpt
指针。
回到主 function,原来的结束指针现在有&pt2
的值。
end->next = newpt;
不应对main
中的原始结束指针产生任何更改,因为仅更改了本地指针。
那么为什么我会得到一个链表。
我得到什么:
(1, -1)
(2, -2)
(3, -3)
我认为我应该得到的:
(1, -1)
如图所示, start
仍然指向p1
, end
指向pt3
。
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);
}
与main
function 一样,您将start
和end
指向pt1
。 这就是为什么从start
也可以看到对end
所做的任何更改。
struct point * append(struct point *end, struct point *newpt){
end->next=newpt;
return newpt;
}
在append
function 中, end->next=newpt
newpt 将end
的next
一个设置为newpt
。 在第一种情况下,当end
pt1
时, next
设置为指向pt2
。 从start
也可以看到列表中的这种变化。
因此,您得到的 output 是正确的。
当您将指针传递给 function 时,指针的值(即地址)被复制到 function 中,而不是它指向的值。
因此,当您取消引用指针并对其进行更改时,也可以从包含相同地址的任何指针中看到更改。 请记住p->next
与(*p).next
相同。
void change_the_pointer_reference(int* ip)
{
int i = 1;
*ip = i;
printf("%d\n", *ip); // outputs 1
}
int main()
{
int i = 0;
change_the_pointer_reference(&i);
printf("%d\n", i); // outputs 1
}
但是随着指针的值被复制,如果你给指针赋值,这种变化只能在本地看到。
void change_the_pointer(int* ip)
{
int i = 1;
ip = &i;
printf("%d\n", *ip); // outputs 1
}
int main()
{
int i = 0;
change_the_pointer(&i);
printf("%d\n", i); // outputs 0
}
最后一点,您的main
签名不正确
end->next = newpt;
不应对main
中的原始结束指针产生任何更改。 因为,只有本地指针被改变了
不太正确。 确实,当您调用append
时,会制作end
的副本。 但是, ->
运算符取消引用该指针指向的内容。 您将与(*end).
. 由于main
中的end
与append
中的end
相同,因此它们都指向同一事物。 您可以拥有 100 个指针副本。 如果你改变其中一个指向的东西,你就会改变它们所有指向的东西。 此外,您通过返回newpt
在main
中重新分配end
,因此对append
的每次调用都有一个更新的end
。 您观察到的 output 是正确的。
最后一点,您有一个不正确的main
签名
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.