Почему здесь уместно иметь двойной указатель (**) на список, а не только один *
, потому что мы хотим изменить значение указателей и вернуть его взвонящий.Точно так же, как вы делаете:
void f(int *x) {
*x = 5;
}
int y;
f(&y);
printf("%d\n", y); // will print 5
Так же, как вы делаете
static int x_mem = 5;
void f(int **x) {
// x is a pointer to (pointer to int)
*x = &x_mem;
}
int *y; // pointer to int
f(&y);
printf("%d %p %p\n", **y, (void*)y, (void*)&x_mem); // will print 5 and two same addresses of `x_mem` variable.
В своей функции вы выделяете память для заголовка списка, если он пуст.Вам нужно вернуть этот указатель на вызывающего, чтобы вызывающий знал, с чего начинается заголовок списка.Итак, вы делаете:
*list = (struct node *) malloc(sizeof(struct node));
Кроме того, почему (* list) в скобках?
Поскольку ->
вычисляется сначала, а затем *
.Это означает, что:
*a->b
анализируется как:
*(a->b)
т.е.:
struct A_s {
int *m;
};
struct A_s *a = malloc(sizeof(struct A_s));
a->m = malloc(sizeof(int));
*a->m = 5;
, однако вы хотите сначала разыменовать указатель и получить доступ к базовой структуре,Т.е. у вас есть:
struct A_s a_mem;
struct A_s *a = &a_mem;
struct A_s **b = &a;
(*b)->m = malloc(sizeof(int)); // equivalent to `a->m` or `(*a).m` or `(**b).m`
*(*b)->m = 5; // equivalent to `*((*b)->m) = ` or `*(a->m) = ` or `*a->m`