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

时间:2019-02-24 13:50:02

标签: c data-structures

我目前正在学习一些基本数据结构的知识,并完成了C中的练习。本实验室正在研究双链表,这是要附加的基本功能。数据结构对我来说很有意义,但我的困惑在于代码。为什么这里有一个指向列表的双指针(**)而不是一个*的指针是合适的。为什么(* list)放在括号中?

我一直在研究指针并通过教程。我理解指针的含义,但是我不确定为什么在这里使用双指针是合适的。

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;
  }
}

为您提供有关该结构的信息,这里是其属性:

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

2 个答案:

答案 0 :(得分:3)

  

为什么在这里有一个指向列表的双指针(**)而不是仅一个*

因为我们要更改指针值并将其返回给调用者。同样的方法:

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`

答案 1 :(得分:0)

如果要将输入参数更改为C中的函数,则需要指针。因此,如果要更改指针,则需要一个指向该指针的指针。没有双指针,*list = (struct node *) malloc(sizeof(struct node));是不可能的。

  

为什么(* list)放在括号中?

因为*list->data将被解释为*(list->data) otherwise。如果要避免所有这些参数,请使用如下所示的临时指针:

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

也不要转换malloc。写入*list = (struct node *) malloc(sizeof(struct node));的适当方法是*list = malloc(sizeof *list);