2013-11-25 197 views
0

我不明白爲什麼這不起作用...例如,我有這個。指針鏈接列表C編程

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

static int length(struct node* head) { 
    Does Stuff 

}; 

void main() ( 
    int i; 
    struct node* head; 
    i = length(head); 
); 

但代碼不想工作...我得到了錯誤的輸出。我試圖發送指針到我的函數,以便他們可以訪問我malloc的數據。我將發佈完整的代碼波紋管:

#include <stdio.h> 
#include <stdlib.h> 

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

static int length(struct node* head); 
static void push(struct node* head, int data); 
static int pop(struct node* head); 
static void appendNode(struct node* head, int data); 
static struct node *copyList(struct node* head); 
static void printList(struct node* head); 



/************************************************************ 
length - return length of a list 
************************************************************/ 
int length(struct node* head) { 
    int count = 0; 
    struct node* current = NULL; 

    current = head; 
    while (current != NULL) { 
     current = current->next; 
     ++count; 
    } 

    return count; 
} 


/************************************************************ 
push - add new node at beginning of list 
************************************************************/ 
void push(struct node* head, int data) { 
    struct node* new_ptr = NULL; 

    new_ptr = (struct node*)malloc(sizeof(struct node)); 
    new_ptr->data = data; 
    new_ptr->next = head; 

    head = new_ptr; 
} 

/************************************************************ 
pop - delete node at beginning of non-empty list and return its data 
************************************************************/ 
int pop(struct node* head) { 
    int val = 0; 
    struct node* temp = NULL; 

    if (head != NULL) { 
     val = head->data; 
     temp = head->next; 
     free(head); 
     head = temp; 
    } 

    return(val); 
} 

/************************************************************ 
appendNode - add new node at end of list 
************************************************************/ 
void appendNode(struct node* head, int data) { 
    struct node* current = NULL; 
    struct node* previous = NULL; 
    struct node* new_ptr = NULL; 

    current = head; 
    previous = current; 
    while (current != NULL) { 
     previous = current; 
     current = current->next; 
    } 

    new_ptr = (struct node*)malloc(sizeof(struct node)); 
    new_ptr->data = data; 
    new_ptr->next = NULL; 

    previous = new_ptr; 

} 

/************************************************************ 
copyList - return new copy of list 
************************************************************/ 
struct node* copyList(struct node* head) { 
    struct node* copy = NULL; 
    struct node* current = NULL; 
    struct node* new_ptr = NULL; 

    /* Copy current head to copy */ 
    current = head; 
    while (current != NULL) { 
     appendNode(copy, current->data); 
     current = current->next; 
    } 

    return copy; 
} 


/************************************************************ 
printList - print linked list as "List: < 2, 5, 6 >" (example) 
************************************************************/ 
void printList(struct node* head) { 
    struct node* current = NULL; 

    printf("List: < "); 

    current = head; 
    if (current == NULL) 
     printf("none "); 

    while (current != NULL) { 
     printf("%d", current->data); 
     current = current->next; 
     if (current != NULL) 
      printf(", "); 
    } 

    printf(" >\n"); 
} 

void main() { 
    int i;      // index used for loops 
    struct node *list_a;  // a new list 
    struct node *list_a_copy; // copy of list 
    list_a = NULL;    // initialize empty list 
    list_a_copy = NULL;   // initialize empy list 


    // test push 
    for (i = 0; i < 4; ++i) 
     push(list_a, i); 

    // test length 
    printf("Length of list = %d\n", length(list_a)); 

    // test print head list 
    printf("head:\n"); 
    printList(list_a); 

    // test append node 
    for (i = 4; i < 8; ++i) 
     appendNode(list_a, i); 

    // test print head list 
    printf("head(append):\n"); 
    printList(list_a); 

    // make a copy of list 
    list_a_copy = copyList(list_a); 

    // test pop head list 
    for (i = 0; i < 4; ++i) 
     printf("%d popped\n", pop(list_a)); 

    // test print copy list 
    printf("head copy:\n"); 
    printList(list_a_copy); 

    // test pop copy list 
    for (i = 0; i < 4; ++i) 
     printf("%d popped\n", pop(list_a_copy)); 

} 

謝謝你的幫助。我仍然在學習這些C指針,我知道我很接近。

乾杯

+0

你問關於hte長代碼還是短代碼? 短代碼將未初始化的指針傳遞給長度函數。那很糟。 – RichardPlunkett

+0

第一個代碼就是一個例子,顯然不是「完整的」。我猜這很混亂,對不起。 – visc

回答

0

我看着功能推():

void push(struct node* head, int data) { 
    struct node* new_ptr = NULL; 

    new_ptr = (struct node*)malloc(sizeof(struct node)); 
    new_ptr->data = data; 
    new_ptr->next = head; 

    head = new_ptr; 
} 

分配head = new_ptr;是錯誤的方式。這樣做,head在函數中有效,head不會指向調用push()後分配的內存。所以你需要修復你的push()函數:

void push(struct node **head, int data) { 
    if ((*head) == null) 
     (*head) = (struct node*)malloc(sizeof(struct node)); 
    (*head)->data = data; 
    (*head)->next = head; 
} 
+0

看編輯,我忘了確認編輯。 – Krypton

0

問題是,您正在將一個指針傳遞給方法中的節點。這意味着您正在修改的是本地參數,而不是您傳遞給該方法的內容。爲什麼是這樣?因爲按值傳遞參數,所以直接複製到地址。

struct Node *list_a = NULL; 
push(list_a, 5); 

當你調用push,會發生什麼是變量list_a的副本壓入堆棧,然後調用該函數。同樣的事情,如果你仔細想想,情況與簡單的情況:

int x = 5; 
add(x, 5); 

void add(int a, int b) { a += b; } // <-- this won't modify the x passed 

所以這裏

void push(struct Node *head, int value) { 
    head = something; 
} 

你沒有修改原始list_a而是已傳遞給它的一個副本功能。

爲了能夠修改原始指針,您需要將地址傳遞給它,所以指向指向列表頭部的指針。這很容易做到:

struct Node *list_a = NULL; 
push(&node, 5); 

void push (struct Node **node, int value) { 
    ... 
    *node = malloc(..); 
} 

所以這裏被傳遞給函數變量list_a的地址,解引用它允許你修改的真正價值,而不是隻是一個副本。