2016-10-20 18 views
0

我正在练习链接列表代码。下面是该插件功能:传递引用时原始值不会改变?

Node* insert_at_pos(Node *head, int pos){  
    struct Node *ptr=NULL; 
    printf("enter data\n"); 
    ptr=(Node*) malloc(sizeof(Node)); 
    scanf("%d",&ptr->data); 
    ptr->next=NULL; 
    if (pos==0){ 
     if (head==NULL){ 
      head=ptr; 
      return head; //return that I want to remove 
     } 
    } 
    printf("done\n"); 
} 

,而不是返回Node*,如果我回到void的,我觉得这个代码应该仍然工作,因为我参照传递价值。因此,head的值应该自动更新而不是返回它,但如果我删除Node*并将void放在返回类型insert_at_pos中,则该值不起作用。

而且,我打电话insert_at_pos功能这样的:

Node *head=insert_at_pos(head,0); 

可能是什么可能的解释或者是怎么回事错在这里?

+2

可能的重复[如何修改已传递到C函数中的指针?](http://stackoverflow.com/questions/766893/how-do-i-modify-a-pointer - 它已被传递到函数在C) –

+1

是的,它绝对是[如何修改已传递到C中的函数的指针](http:// stackoverflow .com/questions/766893/how-do-i-modify-a-pointer-that-has-been-passed-into-a-function-in-c) –

回答

2

基本上有两种方法来处理这个问题。您可以传递指针的地址(键入Node**,传递&head),或者创建一个单独的列表类型。

第二个解决方案将是这个样子:

typedef struct List { 
    Node *head; 
} List; 

一个新的空单可再像这样创建:

List *list = malloc(sizeof (List)); 
list->head = NULL; 

这两种方法都很好。从概念上讲,第二种解决方案更好地匹配实际问题,因为它将列表与数据节点区分开来。您可以创建列表并添加或删除值,而无需更改列表句柄。

第一个解决方案尝试通过让列表头成为列表句柄来跳过列表的单独实体。问题在于空列表没有任何节点,因此空列表由NULL表示。这意味着列表句柄在列表从空变为非空或从非空变为空时发生更改,因此当您插入或删除项目时,列表句柄可能会更改。

使用第一个解决方案的插件功能,可以声明如下:

void insert(Node **head, int value); 

的调用将是这样的:

Node *head = null; 
insert(&head, 42); 

或者它也可以像这样声明(比如在你的问题):

Node* insert(Node *head, int value); 

,并呼吁像这样:

Node *head = null; 
head = insert(head, 42); 
+0

它正在工作。谢谢!但你能解释一下为什么我使用的代码是错误的。概念? –

+1

@SamarYadav这没有错,它只是另一种方式。我添加了一个解释,解释为什么当列表从空变为非空时,插入/删除行为很奇怪。 –

相关问题