【问题标题】:Inserting Node Linked List C插入节点链表 C
【发布时间】:2019-04-26 10:09:11
【问题描述】:

我正在尝试创建一个存储学生姓名和年龄的链接列表。 我在插入时遇到问题。

#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <stdlib.h>

typedef struct node{

  char Name[50];
  int studentAge;
  struct node* next;

}MyNode;

这就是我定义包含所需数据的结构和指向下一个节点的指针'next'的方式。

下面是我的插入函数 所以在第一个if条件中我说如果没有头即头= NULL然后使用malloc为头创建内存空间..之后我将所有数据复制到头节点并确保头的下一个指向空。

在第二种情况下,我是说是否有头部,即头部! = 空 然后使用当前指针遍历列表到末尾,然后将所有数据复制进去。

void InsertStudent(char givenName[50], int age, MyNode* head){

    if(head == NULL){
        head = (MyNode*) malloc(sizeof(MyNode));
        strcpy(head->Name,givenName);
        head->studentAge = age;
        head->next = NULL;
    }


    if(head != NULL){
        MyNode* current = head;
            while(current->next != NULL){
                current = current->next;
            }
        current->next = (MyNode*) malloc(sizeof(MyNode));
        strcpy(current->next->Name,givenName);
        current->next->studentAge = age;
        current->next->next = NULL;
    }

}

现在我不确定我的打印或插入是否有问题,因为当我尝试代码时它不会打印我的节点

void PrintList(MyNode* head){
    MyNode* current = head;

    while(current != NULL){
        printf("Name is %s Age is %d\n",current->Name,current->studentAge);
        current = current->next;
    }

}

这是我的主要功能.. MyNode* head = NULL; 有问题吗?代码行允许吗?

  int main()
   {


    MyNode* head = NULL;

    int r = 0;
while(r!=1)
    {
    printf("Data Structures - Linked List\n");
    printf("Choose one Option:\n\n");
    printf("1.Insert Student\n");
    printf("2.Remove Student\n");
    printf("3.Print all student\n");
    printf("4.Exit\n");

        int option=0;
        char givenName[50];
        int givenAge;
        scanf("%d",&option);

        switch(option){

        case 1:
        printf("Enter name of student:     ");
        scanf("%s",givenName);
        printf("\nEnter Age of student:    ");
        scanf("%d",&givenAge);
        InsertStudent(givenName,givenAge,head);
            break;

        case 2:
        printf("Enter name of student:     ");
        scanf("%s",givenName);
        printf("\nEnter Age of student:    ");
        scanf("%d",&givenAge);
        RemoveStudent(givenName,givenAge);
            break;

        case 3:
        PrintList(head);
            break;
        case 4:
        r=1;
            break;
        default:
        r=1;
        printf("\nNot an option\n");
            break;

       }

    }
}

【问题讨论】:

  • head = (MyNode*) malloc(sizeof(MyNode)) in InsertStudent 对于该函数的调用者来说意味着 nothinghead 指针按值传递。像这样分配给它只会修改一个局部变量;调用者的指针保持不变。要么利用函数的其他未使用的返回值来传达可能更新的头指针,要么通过 address 传递头指针(因此是指向指针的指针)并更改 @987654329 中的代码@ 因此。 SO上至少有一千个这个问题的重复。我会努力追捕一个。
  • 找到一个here。第一个和第二个答案实际上演示了我上面描述的两种方法。
  • 据我所见,您是否试图建议将 void Insert(..) 更改为 MyNode* insert(...) 并返回新节点...或者第二种方法是使用 void (双指针)......这就是你的意思吗?我想用双指针,因为这似乎更难,但我真的不知道该怎么做..
  • 我发布的评论,连同我链接的答案和先前的问题,不可能更好地描述需要做什么。链接问题中的第二个答案精确地显示了如何使用指针到指针的语法来做到这一点。
  • 谢谢。我现在修复它。我刚看到你的第二个帖子,所以我不知道你链接了一个例子

标签: c printing linked-list insertion


【解决方案1】:

您没有将头指针的初始值设置为第一个节点,并且由于从未这样做,因此列表保持为空,并且您会像筛子漏雨水一样泄漏内存。

正如您所传达的,您希望使用指针对指针的语法,结果应如下所示。 (没有错误检查,您可能应该考虑添加):

void InsertStudent(char givenName[50], int age, MyNode** head)
{
    while (*head)
        head = &(*head)->next;

    *head = malloc(sizeof **head);
    strcpy((*head)->Name, givenName);
    (*head)->studentAge = age;
    (*head)->next = NULL;
}

使用头指针的地址从您的主程序中调用(不要将其与您最初正确设置为 NULL 的头指针 in 中的地址混淆;考虑后者指针持有的值,前者作为头指针本身在内存中的位置)。

InsertStudent(givenName,givenAge, &head); // NOTE THIS

我离开了删除和列表清理的任务。

【讨论】:

  • 很抱歉打扰您.. 我不明白这 3 行是做什么的:while (*head) head = &(*head)->next; *head = malloc(sizeof **head);
  • 记住,您传递的是指针的地址。因此,它以指针的形式出现。如果此函数中的head 是指向指针的指针,则*head 是指向的指针的值。这是main 中的原始指针。我强烈建议您使用“C 指针指向指针”的主题来搜索一些 google-fu。或查阅你的文本,如果你有的话。而且,与往常一样,使用调试器单步执行此代码,观察变量的进展,非常具有教育意义。
  • in insert(**head) 我假设 head 实际上是 head 的地址是否正确,所以可以在该函数中将 head 更改为 addresshead 吗?然后 *addresshead 实际上是 head 而 **addresshead 将是实际的第一个节点,它并没有真正影响代码,但它像这样令人困惑.. 我只是确保我的逻辑是正确的
  • 听起来或多或少是准确的。
  • 我有点听从你所说的和想的,现在它的工作我想我现在有点理解双指针了.. 谢谢
【解决方案2】:

您正在按值传递头部;这意味着 InsertStudent 中的行:

head = (MyNode*) malloc(sizeof(MyNode))

它不会更新 main 中的变量“head”。 您想要的是将 &head 传递给 InsertStudent,但是 InsertStudent 必须处理 MyNode **。另一个选项是让 InsertStudent 返回头,因此它的调用是:

 head = InsertStudent(name, age, head);

这两种方式都没有多大关系,有些人更喜欢后者,因为它看起来更功能

在 InsertStudent 内部,您将第一个元素添加了两次。这几乎肯定是不受欢迎的。当你到达线路时:

if(head != NULL){

head 永远不会为 NULL;如果是,您将在上面的 if 语句中分配它。您可能希望此语句为:

else {

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-13
    • 2015-10-20
    • 2013-02-06
    • 1970-01-01
    • 2021-08-23
    • 2021-05-25
    • 2021-07-01
    相关资源
    最近更新 更多