2011-04-20 141 views
1

我有一個問題,我的指針和結構在C(我知道,我知道,很基本!)。我正在練習我的程序範式。這是我第一次使用調試器,因爲在我的生活中我並沒有真正需要它:所以如果你請幫助我,我會很感激。問題與指針在C

我定義了以下結構做一個列表:

typedef struct node { 
    int info; 
    struct node *next; 
    struct node *prev; 
} node_t; 

然後這個函數來填充它:

void addNodo(node_t * list, int x){ 
    node_t * pointer; 
    node_t * temp; 

    temp = (node_t *)malloc(sizeof(node_t)); 
    temp->info = x; 
    temp->next = NULL; 
    temp->prev = NULL; 

    pointer = list; 

    if(pointer == NULL){ //it's empty so start it 
     list = temp; 
     return; 
    } 

    if (pointer->info <= x) { //I like my lists tidy so... 
     while((pointer->next != NULL) && (pointer->info <= x)){ 
      pointer = pointer->next; 
     } 

     if(pointer->next == NULL){ 
      pointer->next = temp; 
      temp->prev = pointer; 
      return; 
     } 

     pointer->next->prev = temp; 
     temp->next = pointer->next; 
     temp->prev = pointer; 
     pointer->next = temp; 
     return; 
    } 
} 

然後,這樣做:

int main(int argc, char** argv) { 
    node_t * list = NULL; 
    addNodo(list, 1); 
    printf("x: %d", list->info); 
    return (EXIT_SUCCESS); 
} 

它拋出了一個分段錯誤!當我調試它時,一切都很有趣,遊戲直到它通過++++行,列表地址回到0x0並且無法使其工作。我知道在某處有一個錯誤,但根據我對指針的瞭解,這非常好。請,檢測我的錯誤,並教我一些指針。

+0

什麼是nodo_t? – TimFoolery 2011-04-20 00:30:44

回答

4

當您撥打addNode()時,您正在通過值傳遞指針。所以當你在函數體中改變它時,變化就會丟失,並且不會傳播到函數之外。您需要將其聲明爲:

void addNode(node_t **pointer, int x) 

,然後在函數中使用*pointer

當你罵,兩者均在主,傳遞&list

+0

非常感謝你,這是正確的在我面前! – fixmycode 2011-04-20 01:09:20

+0

不客氣! – QuantumMechanic 2011-04-20 01:22:17

0

你正在犯一個典型的錯誤:

void addNodo(node_t * list, int x) 
... 

list = temp; 
return; 

list在調用者(主())

沒有改變

您可以更改內存list處的值,但不能更改list的值,並讓調用者看到它。

爲了做到這一點,你需要一個指針傳遞給一個指針到函數:

void addNodo(node_t **list int x) 

這可以讓你做什麼列表點改變:

*list = temp; 
1

問題是你不能修改addNodo函數中的列表。在C參數是通過值發送的,所以你在「addNodo」內部進行的修改對於那裏是本地的。

所以你需要改變addNodo函數,它實際上是接收列表的方向。

void addNode(node_t **list, int x){ 
    ... 
    if(*pointer==NULL){ 
    *list = temp; 
} 
} 

然後在你的主,你應該使用:

addNode(&list, 1); 
1

好吧,你這是按值傳遞列表的地址的錯誤。因此,函數的所有參數都被複制,然後addNodo()對複製的變量起作用。因此原始列表不會被修改。

你應該同時呼籲做的是這樣的:

addNodo(&list, 1); 

在功能上進行這些更改:

void addNodo(node_t ** list, int x) 
/* This will enable you to get a copy of the address of the list variable. 
    Please note that this is also pass by value, C does not support pass by 
    reference */ 

然後,讓這種變化:

pointer = *list; 
    /* this will make the pointer point to the beginning of list as now 
     list is a pointer to pointer type */ 

希望它可以幫助您。

順便說一句,請通過一個標準的C書(我推薦K & R)熟悉在C中傳遞參數和內部發生的事情。