为什么我不能从 C 中的函数传回链表?



我试图通过传递一个指向列表头部的指针来创建一个函数内的链表。在函数内部,一切都很完美。但是当我回到main()时,指针突然变成了NULL。所以如果我再次调用这个函数,它就像我第一次添加一个节点一样。

我的代码有什么问题?

struct course
{
    int c_ID;
    char *c_name;
    struct course *c_next;
};
void new_course(struct course *c_head, struct course *c_tail); // adds a node
int main ( )
{
    // variable declarations
    int choice;
    char y_n;
    // create linked lists
    struct course *c_head = NULL;
    struct course *c_tail = NULL;
    // print out menu, obtain choice, call appropriate function; loop if desired
    do
    {
        printf("ttt***MENU***n"
               " 1. Add a new coursenn"
               ................................
               "Enter the number of the menu option you wish to choose: ");
        scanf("%d", &choice);
        switch (choice)
        {
            case 1:
                new_course(c_head, c_tail);
                if (c_tail == NULL)
                {
                    printf("We're screwed.n"); // this excecutes every time
                }
                break;
            .....................
        }
        printf("Would you like to return to the main menu? Enter y for yes, n for no: ");
        scanf(" %c", &y_n);
    } while (y_n != 'n' && y_n != 'N');
    // free courses
    struct course *c_temp = NULL;
    c_temp = c_head;
    while (c_temp != NULL)
    {
        c_head = c_head->c_next;
        c_temp->c_ID = 0;     // reinitialize the student ID
        c_temp->c_name[0] = ''; // reinitialize the student name string
        free(c_temp->c_name);     // return the string memory to the system
        free(c_temp);         // return the node memory to the system
        c_temp = c_head;      // set temp to next item in the list
    }
    return 0;
}
void new_course(struct course *c_head, struct course *c_tail)
{
    // declare variables
    int ID;
    char name[50];
    // obtain user input
    printf("Enter the course ID number and the course name, separated by a space: ");
    scanf("%d%s", &ID, name);
    if(c_head == NULL) // no courses yet
    {
        c_head = (struct course *) malloc(sizeof(struct course)); // allocate memory for c_head
        c_head->c_next = NULL;
        c_tail = c_head; // update c_tail
    }
    else // the list already has nodes
    {
        c_tail->c_next = (struct course *) malloc(sizeof(struct course)); // allocate memory for new node
        c_tail = c_tail->c_next; // update c_tail
        c_tail->c_next = NULL;
    }
    c_tail->c_ID = ID; // assign ID to c_ID component of new node
    c_tail->c_name = (char *) malloc(sizeof(char) * strlen(name) + 1); // allocate memory for c_name component of new node
    strcpy(c_tail->c_name, name); // assign name to c_name component of new node
    printf("%d = %d, %s = %sn", c_head->c_ID, ID, c_tail->c_name, name); // this always works, proving the list was created and the assignments worked
    return;
}

在C语言中,所有东西都是按值传递的,包括指针。c_headc_tail在主叫上下文中不能被new_course修改。要做到这一点,函数签名需要如下所示:

void new_course(struct course **c_head, struct course **c_tail)

和整个new_course的主体,您需要引用*c_head*c_tail,如:

*c_head = (*c_head)->c_next;

main必须这样调用它:

new_course(&c_head, &c_tail);

您需要将指针传递给指针,以便更改c_head和c_tail的值。

像这样调用

new_course(&c_head, &c_tail);

像这样使用

void new_course(struct course **c_head, struct course **c_tail)
{
    if((*c_head) == NULL) // no courses yet
    {
        (*c_head) = (struct course *) malloc(sizeof(struct course)); 

…等等。

}

我自己不会这样写,但那是你的问题。

C使用按值传递函数参数。

在你的例子中,你使用的是函数

void new_course(struct course *c_head, struct course *c_tail)
用 调用

new_course(c_head, c_tail);

不能,从new_course()函数中,你可以改变c_headc_tail所指向的值,但是你不能改变这两个指针本身。

如果你必须从new_course()更改c_headc_tail,你需要传递一个指针给它们,即指针指向指针。

否则,您有另一个选项来处理这种情况。如果您想简单地传递指针并从函数中更改指针本身,则需要从函数中return修改过的指针,并将其收集到用作参数(并在函数中更改)的相同变量中。然后,更改将反映在调用函数中。

话虽如此,作为提示,

  1. 请参阅为什么不将malloc()和family的返回值强制转换为C
  2. sizeof(char)保证为C中的1。乘以相同是多余的,可以避免。
  3. main()的推荐签名为int main(void)

相关内容

  • 没有找到相关文章

最新更新