我们获得了一个任务和一个链表结构:
typedef struct dlistint_s
{
int n;
struct dlistint_s *prev;
struct dlistint_s *next;
} dlistint_t;
以及以下原型的功能:
dlistint_t *add_dnodeint(dlistint_t **head, const int n);
在创建函数时,有什么优势以及为什么会使用双指针指向头部?
答案 0 :(得分:6)
将指针传递给指向head
的指针的原因是,在调用函数中将看到对指针head
的任何修改,并且您不必从函数返回头部。
例如,请考虑这个简单的节点:
struct Node{
int data;
struct Node *next;
};
将节点添加到前面列表中的功能
struct Node *add_node (struct Node *list, int n){
struct Node *new_node = malloc(sizeof(struct Node));
if(new_node == NULL){
printf("Memory allocation failed\n");
exit(EXIT_FAILURE);
}
new_node->data = n;
new_node->next = list;
return new_node;
}
如果我们需要将new_node
分配给list
而不是返回它,那么我们需要修改上面的函数并删除return语句并发表声明
list = new_node;
但是,不起作用!
这是因为在C中,与所有参数一样,指针是按值传递的。
这意味着list
包含传递给add_node
函数的指针值的副本,而不是传递给此函数本身的指针。
这就是我们需要指向指针的地方。
void add_node (struct Node **list, int n){
struct Node *new_node = malloc(sizeof(struct Node));
if(new_node == NULL){
printf("Memory allocation failed\n");
exit(EXIT_FAILURE);
}
new_node->data = n;
new_node->next = *list;
*list = new_node;
}
答案 1 :(得分:2)
如果使用双指针,则可以传入头部的地址,以便您的函数可以修改实际指针。这样你就不需要返回新头了。
答案 2 :(得分:0)
因为如果您使用dlistint_t *head
变量而不是在函数参数中使用dlistint_t **head
变量,那么函数head
中变量dlistint_t *add_dnodeint(dlistint_t **head, const int n);
中所做的更改将是此方法的本地变量。由于您使用的是Node*
,因此变量head
中的更改对于该函数是本地的。如果你想在函数调用之后反映这些变化(你显然想要),那么使用dlistint_t **head
。