2015-08-29 36 views
0

我有一個關於通過函數傳遞C中鏈接列表的頭部的問題。所以代碼如下所示:傳遞一個鏈接列表頭通過函數作爲地址在C

#include <stdio.h> 
//Defining a structure of the node 
struct node { 
    int data; 
    struct node* next; 
    }; 

void insert (struct node* rec, int x) { 
    struct node* temp = (struct node*)malloc(sizeof(struct node)); 
    temp->data = x; 
    temp->next = NULL; 
    rec = temp; // head and rec is now pointing to the same node 
} 

void print(struct node* rec){ 
    printf("%d", rec->data); //error occurs here 
    puts(""); 
} 

main(){ 
    struct node *head = NULL; //head is currently pointing to NULL 
    insert (head, 5); //Passing the head pointer and integer 5 to insert() 
    print(head); 
} 

因此,如您所見,當我嘗試打印rec->數據時發生錯誤。爲什麼發生錯誤?因爲指針rec和head都指向堆中的同一個節點,所以應該沒有問題?

謝謝。

+5

您需要通過'struct node **'來插入,就像'insert(&head ...'。否則頭不會改變,因爲函數只接收它的值的副本。 – sje397

+0

您可以將列表的頭部通過重新定義'insert'函數的參數 –

+0

並且你可能想'temp-> next = * rec'(假設你傳遞了一個雙指針),否則你將失去列表的其餘部分。 – sje397

回答

3

你可以通過一個struct node**通過@ sje397的建議。

不過,我建議下面的設計(這在我看來是比較容易推理太):

/* returns the new head of the list */ 
struct node *insert (struct node* current_head, int x) { 
    struct node* temp = (struct node*)malloc(sizeof(struct node)); 
    temp->data = x; 
    temp->next = current_head; 
    return temp; 
} 

,並使用它像

head = insert(head, 5); 

在這種情況下,我也重命名該功能,如push_front

只是爲了保持完整性,我覺得@ sje397意味着類似如下(以每C程序員重寫一遍又一遍典型的鏈表代碼...):

void insert(struct node **head, int x) { 
    struct node* new_head = (struct node*)malloc(sizeof(struct node)); 
    new_head->data = x; 
    new_head->next = *head; 

    *head = new_head; 
} 
+0

是的,這樣更好。 – sje397

+0

我看... @ sje397 nimrodm非常感謝你的幫助!這個指針指針的指針讓我每次都感到困惑。 – Luna

-1

重新定義insert功能:

void insert (struct node** rec, int x) { 
    struct node* temp = (struct node*)malloc(sizeof(struct node)); 
    temp->data = x; 
    temp->next = NULL; 
    *rec = temp; // head and rec is now pointing to the same node 
} 
+0

修正了上面提到的bug,但它不是插入函數 – sje397

+0

調用這個函數會給你指向NULL的節點,所以如果你考慮鏈表是如何構造的,這並不真正提供插入功能。您需要修改'rec',以便新節點指向它,反之亦然。 –

0

在C沒有通過引用傳遞。
您的插入函數並未在列表中插入一個節點,它只是更改頭指向的節點。由於temp->next = NULL該列表將始終包含兩個節點。

另一個錯誤是您只是修改頭節點的本地副本。 爲了解決這個問題,您有3種選擇:

- 可以使頭節點全球

- 可以將一個指針傳遞到頭節點(指針的指針)的功能。

- 您可以通過函數返回修改的頭節點。

相關問題