2011-04-20 84 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中传递参数和内部发生的事情。