从链接列表中追加和读取的函数

时间:2014-06-27 13:15:31

标签: c pointers linked-list

我正在研究一个可以在链表上执行2个功能的小型测试程序:

  1. 将某些内容附加到链接列表中。
  2. 得到附加的东西。
  3. 所以我编写了两个可以执行此功能的函数。但它不起作用。 如果我调用函数append_work(),它会打印出它附加了工作以及我传递的正确值。但是之后它似乎没有正确地将指针设置为下一个结构。我不知道为什么会这样。

    当我调用get_work()时,会发生类似的事情,它会正确打印当前的工作,但不会将其设置为下一个工作。 outptr只在那里,所以它返回要完成的工作的结构,而stil将work_travel设置为下一个!

    我可能错过了一些非常明显的指针,但我没有看到它......

    这是代码。它编译:

    #define          _POSIX_C_SOURCE                             200809L  
    #define          ERRNO_BUFSIZE                               256
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <unistd.h>
    
    int strerror_r(int errnum, char *buf, size_t buflen);
    
    typedef struct work work;
    
    struct work {
    
        char                *str;
        int                 i;
        work                *next;
    
    };
    
    int append_work(work *ptr, char *work, int i) {
        char    strerror_buf[ERRNO_BUFSIZE];
    
        ptr->next = malloc(sizeof(work));
        if (ptr == NULL) {
            strerror_r(errno, strerror_buf, ERRNO_BUFSIZE);
            printf("malloc() err: %s\n",strerror_buf);
            return -1;
        }
    
        ptr = ptr->next;
        ptr->str=work;
        ptr->i=i;
        printf("appending work: %s\n",ptr->str);
    
        ptr->next = NULL;
    
        return 0;
    
    }
    
    int get_work(work *inptr, work *outptr) {
    
        if (inptr == NULL) {
            printf(" No work found...\n");
            return -1;
        } else {
            outptr = inptr;
            printf(" work found: str: %s|| int: %d\n",inptr->str, inptr->i);
            inptr = inptr->next;
            return 0;
        }
    }
    
    
    
    int main() {
    
        char                strerror_buf[ERRNO_BUFSIZE];
    
        work                *root;
        work                *work_travel;
        work                *add_work;
        work                *curr_work;
    
        root = malloc(sizeof(work));
        if (root == NULL) {
            strerror_r(errno, strerror_buf, ERRNO_BUFSIZE);
            printf("malloc() err: %s\n",strerror_buf);
            exit(1);
        }
        root->str="work 0";
        root->i=0;
    
    
        work_travel = root;
        add_work = root;
    
        append_work(add_work, "work 1", 1);
        append_work(add_work, "work 2", 2);
        append_work(add_work, "work 3", 3);
        append_work(add_work, "work 4", 4);
        append_work(add_work, "work 5", 5);
        append_work(add_work, "work 6", 6);
        append_work(add_work, "work 7", 7);
        append_work(add_work, "work 8", 8);
        append_work(add_work, "work 9", 9);
    
        get_work(work_travel, curr_work);
        get_work(work_travel, curr_work);
        get_work(work_travel, curr_work);
    
        exit(1);
    
    }
    

2 个答案:

答案 0 :(得分:1)

您永远不会返回列表中的新头,您在ptr内更改了append_work(),但add_workmain()的值未发生变化。

您应该返回新的列表头。

这是因为C严格call by value;参数是调用者上下文中相同值的副本,更改副本不会影响调用者的值。值的类型无关紧要,它始终是副本。

答案 1 :(得分:1)

首先,让&#34; struct work&#34;,一个名为&#34; work&#34;的类型,一个名为&#34;&#34;的工作&#34;是真的糟糕的编程风格。

也就是说,问题是inptrget_work中的局部变量,当您调用work_travel时,更改它不会更改get_work(work_travel, curr_work)。你必须以某种方式返回更新的值,或者作为get_work的返回值(尽管使用此解决方案,你松开了成功标志,而不是你使用它:-)):

work *get_work (work *inptr, work *outptr) {
   ...
   return inptr;
}

并称之为:

work_travel = get_work(work_travel, curr_travel);

或者传入一个指向待更新对象的指针,如:

int get_work (work **inptr_p, work *outptr) {
  work *inptr = *inptr_p;
  if (inptr == NULL) {
    printf(" No work found...\n");
    return -1;
  } else {
    outptr = inptr;
    printf(" work found: str: %s|| int: %d\n",inptr->str, inptr->i);
    inptr = inptr->next;
    *inptr_p = inptr;
    return 0;
  }
}
...
get_work (&work_travel, curr_travel);