简体   繁体   English

C-大括号内的指针和双指针

[英]C - Pointer inside curly brackets and double pointers

I am currently learning some stuff on basic data structures and completing the exercises in C. This lab is looking at doubly linked lists, and this is the basic function to append. 我目前正在学习一些有关基本数据结构的知识,并完成了C中的练习。本实验室正在研究双链表,这是要附加的基本功能。 The data structure makes sense to me but my confusion is with the code. 数据结构对我来说很有意义,但我的困惑在于代码。 Why is it appropriate here to have a double pointer (**) to the list rather than just the one *. 为什么这里有一个指向列表的双指针(**)而不是一个*的指针是合适的。 Also why is (*list) in brackets? 还有为什么(* list)放在括号中?

I have been researching pointers and going through tutorials. 我一直在研究指针并通过教程。 I understand what the pointers mean but I'm not sure why a double pointer is appropriate here. 我理解指针的含义,但是我不确定为什么在这里使用双指针是合适的。

void append(struct node ** list, int num,)
{
  struct node *temp, *current = *list;
  if(*list == NULL)
  {
    *list = (struct node *) malloc(sizeof(struct node));
    (*list) -> prev = NULL;
    (*list) -> data = num;
    (*list) -> next = NULL;
  }
  else
  {
    while(current -> next != NULL)
    {
      current = current -> next;
    }

    temp = (struct node *) malloc(sizeof(struct node));
    temp -> data = num;
    temp -> next = NULL;
    temp -> prev = current;
    current -> next = temp;
  }
}

to give you information on the struct here are its properties: 给您有关该结构的信息,这里是它的属性:

struct node
{
  int data;
  struct node * prev;
  struct node * next;
};

Why is it appropriate here to have a double pointer (**) to the list rather than just the one * 为什么在这里有一个指向列表的双指针(**)而不是仅一个*

Because we want to change the pointers value and return it to the caller. 因为我们要更改指针值并将其返回给调用者。 The same way you do: 使用相同的方法:

void f(int *x) {
    *x = 5;
}

int y;
f(&y);
printf("%d\n", y); // will print 5

The same way you do 同样的方法

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.

In your function you allocate the memory for the list head if it's empty. 在您的函数中,如果列表头为空,则为列表头分配内存。 You need to return that pointer to the caller, so the caller knows where the list head starts. 您需要将该指针返回给调用者,以便调用者知道列表头从何处开始。 So you do: 所以你也是:

*list = (struct node *) malloc(sizeof(struct node));

Also why is (*list) in brackets? 还有为什么(* list)放在括号中?

Because -> is evaluated first then * . 因为->首先被评估,然后是* That means that: 这意味着:

*a->b

is parsed as: 解析为:

*(a->b)

ie: 即:

struct A_s {
   int *m;
};
struct A_s *a = malloc(sizeof(struct A_s));
a->m = malloc(sizeof(int));  
*a->m = 5;

however you want to first dereference the pointer and access the underlying structure. 但是,您首先要取消引用指针并访问底层结构。 Ie you have: 即您有:

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`

If you want to change the input parameters to a function in C, you need pointers. 如果要将输入参数更改为C中的函数,则需要指针。 So if you want to change a pointer, then you need a pointer to pointer. 因此,如果要更改指针,则需要一个指向该指针的指针。 Without a double pointer, *list = (struct node *) malloc(sizeof(struct node)); 没有双指针, *list = (struct node *) malloc(sizeof(struct node)); would not be possible. 将不可能。

Also why is (*list) in brackets? 还有为什么(* list)放在括号中?

Because *list->data would be interpreted as *(list->data) otherwise . 因为*list->data *(list->data) otherwise将被解释为*(list->data) otherwise If you want to avoid all those parameters, use a temporary pointer like this: 如果要避免所有这些参数,请使用如下所示的临时指针:

void foo(int ** bar) {
    int * ptr = *bar;
    ptr->x = 42; // Equivalent to (*bar)->x=42;
}

And don't cast malloc. 并且不要转换malloc。 The appropriate way to write *list = (struct node *) malloc(sizeof(struct node)); 编写*list = (struct node *) malloc(sizeof(struct node));的适当方法*list = (struct node *) malloc(sizeof(struct node)); is *list = malloc(sizeof *list); *list = malloc(sizeof *list);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM