2014-07-22 53 views
2

我发现这个链接列表例程(来自Haviland的Unix系统编程)将一个项目添加到单个链接列表中。头部指针指针

additem(item **head, item *newitem) 
{ 
    newitem->next = *head; 
    *head = newitem; 
} 

我的难处在于试图理解item **head部分。 **head究竟意味着什么?

additem(item *head, item *newitem) 
{ 
    newitem->next = head; 
    head = newitem; 
} 

回答

3

这是一个指针的指针:为什么不只是item *head如下定义程序。

在C中,您无法更改通过值传递的变量,因为参数是作为局部变量处理的。您必须改为指针,然后修改*variable的值。

当你想改变的变量已经是一个指针时,它也适用。在这种情况下,您必须将指针传递给该指针,因此当您更改此指针时,此更改会传播给调用者。

*head是价值head指向。而head类型为item **,*head的类型为item *

当你这样做:

additem(item *head, item *newitem) 
{ 
    newitem->next = head; 
    head = newitem; 
} 

修改的head的值不会影响它的值给调用者。出于所有目的,在这种情况下更改head是没有意义的。

0

如果您只是将指针*head传递给子例程并更改它的值并尝试返回它,那么您会发现不能这样做,因为它是一个传递给只存在于例程堆栈上的例程的值,只要例程在范围内。但是,您可以将指针传递给该指针(**head,它也将在堆栈中本地),然后更改它指向的值,然后在调用例程的范围中更改要更改的值实际上已经改变。

这是通过引用实现调用的'C方式',尽管C只正式支持按值调用—它使用值的调用,并且该值的值是对所需对象的引用改变,从而允许通过引用来调用。

1

您的题目中有第一个问题的答案:item **head表示head是指向指针的指针。

为什么你的第二个代码片段不起作用?因为

head = newitem; 

分配值到当地变量head,这不是什么代码打算这样做。

0

只要明白一点:如果你想要另一个函数来改变一个变量的值。你必须通过它的地址,因为C使用“按价值调用”机制。

void change_value(type *a) 
{ 
    *a = ...; 
} 

在这种情况下,你想一个指针的值更改为型(头*),所以它的地址有头的类型**

型* 一个等于到(头*)*一个头**一个