比如如下代码
-
void create3(List* head, int *a, int n)
-
{
-
printf("head2 = 0x%x\n", head);
-
head = (List*)malloc(sizeof(List));
-
head->val = 1;
-
head->next = NULL;
-
printf("head4 = 0x%x\n", head);
-
}
-
int main()
-
{
-
int a[] = {3, 1, 5, 4, 7, 9, 2};
-
int i, len = sizeof a / sizeof a[0];
-
List* head;
-
printf("head1 = 0x%x\n", head);
-
create3(head, a, len);
-
printf("head3 = 0x%x\n", head);
-
}
经常会在写链表的时候犯这个错误,曾经也百思不得其解,为什么最后会错呢?其实不难理解,我们看最后的输出吧:
head1 = 0x28ff94
head2 = 0x28ff94
head4 = 0x910e98
head3 = 0x28ff94
发现head4与其他几值不一样了,但是当函数结束了,head3还是之前的值,也就是说这个head进函数之后返回依然没有改变其值。不妨分析一下,首先,在main函数里面定义了结构体指针head,也没有初始化他,此时head指向的什么乱七八糟的也不知道,当以传值的方式进入函数以后,事实上create3把参数List* head拷贝了一份,然后修改了head的值,但是主函数里面的head是无辜的,他没有修改。是不是很眼熟,那个熟悉的swap的例子就是类似的原理,除非用C++的引用。
一个可行的方法,在不改变主函数的方式下:
-
void create2(List** head, int *a, int n)
-
{
-
*head = (List*)malloc(sizeof(List));
-
(*head)->next = NULL;
-
create(*head, a, n);
-
}
-
-
int main()
-
{
-
/// .......
-
create2(&head, a, len);
-
/// .......
-
}
以传递指针的指针传递进去,也就是传递head的地址,这个时候其实把head的地址传递进去了,那head的地址是没有修改过的,但是head的值仍然是个结构体的地址,修改了head的值之后,主函数的也随着修改了。一句话,函数改变了head里面的值,但是传递的地址没有修改,虽然是拷贝过去的。画个图
分别表示传递前和传递后的状态。分别表示&head和head,我们发现head的值是变过了,但是head的地址依旧是那个!
阅读(221) | 评论(0) | 转发(0) |