我在C中创建了一个带有链表的程序。我在main
函数中创建了head
变量。然后我通过引用函数insert_at_head(struct node **head)
来传递它。
我还有一个在尾部插入的函数。在基本条件下,如果我的列表为空,我想再次调用insert_at_head(struct node **head)
。但我在传递实际参数时感到困惑。应该是insert_at_head (&(*head))
还是insert_at_head (head)
?
就我个人而言,我认为两者都是一样的,因为他们都在传球。我应该用哪一个?
关于insert_at_head
函数,您必须记住,在C中,所有参数都是通过值传递的。这意味着该值被复制到参数变量中。在函数内部,如果修改参数变量(如赋值(,则只修改副本,而不修改原始变量。
如果要修改原始值,则必须模拟逐引用传递,这可以通过使用运算符&
的地址传递指向该值的指针来完成。如果你想对一个作为指针的变量这样做,那么你会得到一个指向指针的指针。
这里有一个简单的例子:
#include <stdio.h>
// Define two global variables
int a = 10;
int b = 20;
void change1(int *x)
{
x = &b; // Make x point to b
}
void change2(int **x)
{
*x = &b; // Make *x point to b
}
int main(void)
{
// Define a pointer variable, and make it point to the global variable a
int *pointer_to_a = &a;
// Will print the value of a, i.e. 10
printf("*pointer_to_a = %dn", *pointer_to_a);
// Try to change where pointer_to_a is pointing
change1(pointer_to_a);
// Here pointer_to_a is *still* pointing to a, it wasn't changed, will print the value 10
printf("*pointer_to_a = %dn", *pointer_to_a);
// Do another attempt to change where pointer_to_a is pointing
change2(&pointer_to_a);
// Now pointer_to_a is no longer pointing to a, it points to b and 20 will be printed
printf("*pointer_to_a = %dn", *pointer_to_a);
}
回到insert_at_head
函数(我们只能推测其功能(,我猜它会添加到链表的头部。它将通过修改列表头所指向的位置来实现这一点。
正如上面的例子所示,除非我们将指针传递给指针,否则一旦函数结束,对头的赋值就会丢失。这是通过使用指针到指针,并在调用函数时使用运算符&
的地址传递头指针来解决的。
假设head
的类型为struct node **
,则可以将其直接传递给期望该类型参数的函数。
CCD_ 13与CCD_。当&
运算符的操作数是一元*
运算符的结果时,它们相互抵消,实际上都不会求值。
这在C标准的第6.5.3.2p3节中详细说明了有关地址和间接运算符的内容:
一元
&
运算符产生其操作数的地址。如果操作数的类型为",结果的类型为指向类型"的">如果操作数是一元*
运算符的结果运算符和&
运算符都不进行求值,结果就好像两者都被省略了,除了对运算符的约束仍然应用,结果不是左值。
因此,如果head
是指针,则表达式head
和&(*head)
是等价的。
在C语言中,您不能通过引用传递变量。
但是,您可以向变量传递指针。当然,指针是按值传递的。例如,如果您声明一个可变head
,它是指向结构node
:的指针
struct node* head;
您可以准备一个函数来操作这样的变量:
void insert_at_head(struct node** ptr);
然后你用来称呼它
insert_at_head(&head);
其中运算符&
产生一个指向变量的指针,即struct node **
类型的值。值被传递给被调用者。
当然,还有一个功能,比如:
void append_at_end(struct node** ptr);
可以在必要时调用前一个函数,将得到的指针作为参数传递给它:
void append_at_end(struct node** ptr)
{
if(*ptr == NULL) /* list is empty */
insert_at_head(ptr); /* the same pointer to a head pointer */
else {
/* other stuff */
}
}
应该是insert_at_head(&(*head((还是insert_at_head(head(?
没有。他们都错了,也都一样。
如果你在主菜单中做了以下操作:
struct node head;
您的代码将开始出现问题。
你可以让它发挥作用,但这是错误的方式。
要使其发挥作用,您必须在主菜单中执行以下操作:
struct node head;
struct node *phead=&head;
insert_at_head(&phead).
正确的做法是:
struct node *head=NULL;
insert_at_head(&head).