假设相关的头文件,声明了C中的单链接列表函数。
Delete()的以下定义正确吗?
/* The Structure for SLL
typedef struct SLL
{
int data;
struct SLL *next;
}node;
Function Delete() deletes a node*/
void Delete( node **head)
{
node *temp, *prev;
int key;
temp = *head;
if(temp == NULL)
{
printf("\nThe list is empty");
return;
}
clrscr();
printf("\nEnter the element you want to delete:");
scanf("%d", &key);
temp = search( *head , key);//search()returns the node which has key
if(temp != NULL)
{
prev = get_prev(*head, key);
if(prev != NULL)
{
prev->next = temp->next;
free(temp);
}
else
{
*head = temp->next;
free(temp);
}
printf("\nThe node is deleted");
getch();
}
}
1)如果我将(node ** head)
替换为(node *head)
,会发生什么?
2)如果我将void Delete (node **head)
替换为node会发生什么?
*Delete(node *head)
?
3)是否有另一种方法可以删除C中的节点?
预先感谢
答案 0 :(得分:2)
这不是教程网站,但是这里...
您知道C中的参数是通过值传递 的吗?表示该值为已复制。
例如:
void some_function(int a)
{
// ...
}
调用上面的函数时,例如
int x = 5;
some_function(x);
然后将x
中的值复制到函数中的参数a
中。如果函数中的代码分配给a
(例如a = 12;
),那么您仅修改局部变量a
,即副本。它不会修改原始变量。
现在,如果我们想要修改x
的函数,那么我们必须模拟通过引用传递,这是通过使用指针和地址的运算符:
void some_function(int *a)
{
*a = 12; // Modify where a is pointing
}
现在要调用它,我们不创建指针变量并将其传递(尽管也可以),而是使用地址操作符&
将指针传递给该变量:>
int x = 5;
some_function(&x); // Pass a pointer to the variable x
指针&x
将按值传递(因为这是在C中传递参数的唯一方法),但是我们不想修改指针,我们想修改数据指向的位置。
现在回到您的特定函数:您的函数想要修改一个变量,该变量是一个指针,那么我们如何模拟按引用传递?通过将指针传递给指针。
如果有的话
node *head;
// Initialize head, make it point somewhere, etc.
现在,由于Delete
函数需要修改head points, we pass a pointer to
头的位置,即指向该指针的指针:
Delete(&head);
Delete
函数当然必须接受该类型,即指向node
的指针的指针,即node **
。然后,它使用解引用运算符*
来获取指针指向的位置:
*head = temp->next;
答案 1 :(得分:1)
1)如果将node** head
替换为node* head
,则不会修改原始的head
指针。您可能在某个head
位置标记了链接列表的开始。删除节点时,有可能要删除head
。在这种情况下,您需要修改head
以指向链接列表中的下一个node
。
*head = temp->next;
free(temp);
这部分代码正是这样做的。在这里,temp == head
。我们希望head
指向head->next
,但是如果我们将node* head
传递给函数,则指针将被修改,但更改将消失,因为您正在按值传递指针。如果您想使更改反映在函数外部,则需要传递&head
类型的node ** head
。
2)然后,您将更改函数定义以返回一个空指针(这是一个可以转换为任何指针的占位符指针。请注意不要破坏任何别名规则。但是(1)中的问题仍然存在,尽管如此,您可以返回修改后的head并将其分配给返回的值,在这种情况下,定义该函数与其他不需要修改head的情况不太适合,因此您可以返回一个指针如果已修改则返回head,否则返回NULL。尽管如此,这还是做些杂乱的方法。
3)是,但这取决于实现链表的方式。对于此处显示的数据类型,基本删除操作已给出。