此链接列表未更改,在main函数中不起作用

时间:2016-03-31 11:22:43

标签: c pointers linked-list

#include <stdio.h>
#include <stdlib.h>
struct listnode{
    int value;
    struct listnode *nextnode;
};
typedef struct listnode listnode;

void printlist(listnode *sptr){
    if(sptr == NULL){
        printf("No list!\n");
    }
    else{
        printf("The list is:");
        while(sptr != NULL){
            printf("%d-->",sptr->value);
            sptr = sptr->nextnode;
        }
        printf("NULL\n");
    }
}
void insert(listnode *sptr, int item){
    listnode *newptr = malloc(sizeof(listnode));
    if(newptr != NULL){
        newptr->value = item;
        newptr->nextnode = sptr;
        sptr = newptr;
    }
    else{
        printf("No enough memory!\n");
    }
}

int main(){
    listnode *startptr = NULL;
    insert(startptr, 1);
    insert(startptr, 2);
    printlist(startptr);
}

以上是我的代码,它可以编译,但是,在main函数中,当我调用printlist时,它不是print(2->1->NULL),它打印No list.I尝试在insert函数内打印列表,(在sptr = newptr之后),我使用printlist(sptr),第一次,它带有(1->NULL),第二次带有(2->NULL)。我认为每次问题都是insert(&startptr, 1); startptr没有改变?为什么呢?

3 个答案:

答案 0 :(得分:2)

你好像不知道C是&#34;按价值呼叫&#34;。

当您更改函数内部参数的值时,调用者的参数不会更改。

这(在TAB <- table(pred, winevalid$class) # table of preditions vs. original classifications TAB # pred barolo grignolino barbera # barolo 29 1 0 # grignolino 1 30 0 # barbera 0 1 27 sum(diag(TAB)) / sum(TAB) # overall accuracy # [1] 0.9662921 中):

insert()

没有意义,它对来电者的sptr = newptr; 变量没有任何影响。

考虑返回列表的新头。

顺便说一下,考虑一下这样的函数:

startptr

在&#34;你的世界&#34;中,上面会尝试通过重新分配void foo(int x) { printf("in foo(), x=%d\n", x); x = 0; } int main(void) { foo(17); } ,即参数17的来电者值,等于0 。但是当然(?)重新分配一个文字的值是没有意义的,这是一个很好的提示,它不像你想象的那样工作。嗯。或许这只会增加更多的混淆,它可能有点主观。

答案 1 :(得分:2)

如果您希望更新指针本身以指向新位置,则需要将指针传递给指针。

void insert(listnode **sptr, int item){
    listnode *newptr = malloc(sizeof(listnode));
    if(newptr != NULL){
        newptr->value = item;
        newptr->nextnode = sptr;
        *sptr = newptr;
    }
    else{
        printf("No enough memory!\n");
    }
}

int main(){
    listnode *startptr = NULL;
    insert(&startptr, 1);
    insert(&startptr, 2);
    printlist(startptr);
}

答案 2 :(得分:0)

函数参数是退出函数后销毁的局部变量。

您可以想象函数insert及其调用方式

insert(startptr, 1);

void insert( /*listnode *sptr, int item */){
   listnode *sptr = startptr;
   int item = 1;
   //...

因此,函数中局部变量sptr的任何更改都不会影响原始参数startptr。调用函数后,startptr将保持不变。

您应该通过引用传递标头节点或从函数返回新的标头节点。

因此可以像

那样定义函数
void insert(listnode **sptr, int item){
    listnode *newptr = malloc(sizeof(listnode));
    if(newptr != NULL){
        newptr->value = item;
        newptr->nextnode = *sptr;
        *sptr = newptr;
    }
    else{
        printf("No enough memory!\n");
    }
}

并调用

insert(&startptr, 1);

或者可以将功能定义为

listnode * insert(listnode *sptr, int item){
    listnode *newptr = malloc(sizeof(listnode));
    if(newptr != NULL){
        newptr->value = item;
        newptr->nextnode = sptr;
        sptr = newptr;
    }
    else{
        printf("No enough memory!\n");
    }

    return sptr;
}

并调用

startptr = insert(startptr, 1);