仍携书剑路茫茫 2024-12-03 10:53 采纳率: 40%
浏览 5

为什么创建了几个商品后,删除头节点,再打印信息,还是会使用已删除头节点的地址

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#pragma warning(disable : 4996)
//创建商品
struct good
{
    int number, importCount, sellCount;
    float importPrice, exportPrice;
    char name[10];
    struct good* next;
};

//创建节点
struct good* createNode(int number, const char* name, int importCount, int sellCount,
    float importPrice, float exportPrice)
{
    struct good* newNode = (struct good*)malloc(sizeof(struct good));
    if (newNode == NULL)
    {
        printf("错误");
        exit(1);
    }
    strcpy(newNode->name, name);
    newNode->exportPrice = exportPrice;
    newNode->importCount = importCount;
    newNode->importPrice = importPrice;
    newNode->number = number;
    newNode->sellCount = sellCount;
    newNode->next = NULL;
    return newNode;
}

//尾部插入节点
void insertNode(struct good** head, int number, const char* name, int importCount, int sellCount,
    float importPrice, float exportPrice)
{
    struct good* newNode = createNode(number, name, importCount, sellCount,
        importPrice, exportPrice);
    if (*head == NULL)
    {
        *head = newNode;
        return;
    }
    struct good* temp = (*head);
    while (temp->next != NULL)
    {
        temp = temp->next;
    }
    temp->next = newNode;
}

//打印链表
void printList(struct good* head)
{
    if (head == NULL)
    {
        printf("内容为空,无法打印\n");
        return;
    }
    while (head != NULL)
    {
        printf("编号%d 品名%s 进价%.2f 售价%.2f 进货量%d 销售量%d 销售额%.2f 剩余数%d 毛利%.2f\n", head->number,
            head->name, head->importPrice, head->exportPrice, head->importCount, head->sellCount,
            head->exportPrice * head->sellCount, head->importCount - head->sellCount, head->exportPrice * head->sellCount - head->importPrice * head->sellCount);
        head = head->next;
    }
}

//释放链表
void freeList(struct good* head)
{
    if (head == NULL)
        return;
    struct good* temp;
    while (head != NULL)
    {
        temp = head;
        head = temp->next;
        free(temp);
    }
}

//创建商品信息
void createGood(struct good** head)
{
    int number, importCount, sellCount;
    float importPrice, exportPrice;
    char name[10];
    printf("请输入品名: ");
    scanf("%9s", name);
    printf("请输入编号: ");
    scanf("%d", &number);
    printf("请输入进价: ");
    scanf("%f", &importPrice);
    printf("请输入售价: ");
    scanf("%f", &exportPrice);
    printf("请输入进货量: ");
    scanf("%d", &importCount);
    printf("请输入销售量: ");
    scanf("%d", &sellCount);
    insertNode(head, number, name, importCount, sellCount, importPrice, exportPrice);
    while (getchar() != '\n');
}

//删除商品
void deleteGood(struct good** head)
{
    int key;
    printf("输入要删除商品编号:");
    scanf("%d", &key);
    if (*head == NULL)
    {
        printf("链表为空,结束!");
        return;
    }
    else if ((*head)->number == key)
    {
        struct good* temp = *head;
        *head = temp->next;
        free(temp);
        return;
    }
    else
    {
        struct good* temp = *head;
        struct good* current = NULL;
        while (temp != NULL && temp->number != key)
        {
            current = temp;
            temp = temp->next;
        }
        if (temp == NULL)
        {
            printf("找不到要删除商品!\n");
            return;
        }
        else if(temp->next!=NULL&&temp->number==key)
        {
            current->next = temp->next;
            free(temp);
            return;
        }
        else
        {
            current->next = NULL;
            return;
        }
    }
}

//编辑商品信息
void changeGood(struct good* head)
{
    int key1;
    printf("输入要修改商品编号:");
    scanf("%d", &key1);
    struct good* temp = head;
    while (temp != NULL && temp->number != key1)
    {
        temp = temp->next;
    }
    if (temp == NULL)
    {
        printf("错误");
        exit(1);
    }
    printf("请输入品名: ");
    scanf("%9s", temp->name);
    printf("请输入编号: ");
    scanf("%d", &(temp->number));
    printf("请输入进价: ");
    scanf("%f", &(temp->importPrice));
    printf("请输入售价: ");
    scanf("%f", &(temp->exportPrice));
    printf("请输入进货量: ");
    scanf("%d", &(temp->importCount));
    printf("请输入销售量: ");
    scanf("%d", &(temp->sellCount));
}

//统计销售情况
void statGood(struct good* head)
{
    while (head != NULL)
    {
        printf("%s销售 %d\n", head->name, head->sellCount);
        head = head->next;
    }
}

//按剩余数查询
void findCount(struct good* head)
{
    int key1;
    printf("输入要查询剩余数:");
    scanf("%d", &key1);
    while (head != NULL)
    {
        if (head->importCount - head->sellCount == key1)
            printf("编号%d 品名%s 进价%.2f 售价%.2f 进货量%d 销售量%d 销售额%.2f 剩余数%d 毛利%.2f\n", head->number,
                head->name, head->importPrice, head->exportPrice, head->importCount, head->sellCount,
                head->exportPrice * head->sellCount, head->importCount - head->sellCount, head->exportPrice * head->sellCount - head->importPrice * head->sellCount);
        head = head->next;
    }
    if (head == NULL)
    {
        printf("输入错误!");
    }
}

//按品名查询
void findName(struct good* head)
{
    char key[10];
    printf("输入要查找品名:");
    fgets(key, sizeof(key), stdin);
    key[strcspn(key, "\n")] = '\0';
    while (strcmp(head->name, key) != 0 && head != NULL)
    {
        head = head->next;
    }
    if (head == NULL)
    {
        printf("输入错误");
        exit(0);
    }
    printf("编号%d 品名%s 进价%.2f 售价%.2f 进货量%d 销售量%d 销售额%.2f 剩余数%d 毛利%.2f\n", head->number,
        head->name, head->importPrice, head->exportPrice, head->importCount, head->sellCount,
        head->exportPrice * head->sellCount, head->importCount - head->sellCount, head->exportPrice * head->sellCount - head->importPrice * head->sellCount);
}

//按毛利高低显示
void orderProfit(struct good* head)
{

    if (head == NULL)
        return;
    struct good* i, * j;
    int temp1, temp3;
    float temp4, temp2;
    for (i = head; i != NULL; i = i->next)
    {
        for (j = i->next; j != NULL; j = j->next)
        {
            if (i->sellCount * i->exportPrice - i->sellCount * i->importPrice < j->sellCount * j->exportPrice - j->sellCount * j->importPrice)
            {
                temp1 = i->sellCount;
                temp2 = i->exportPrice;
                temp3 = i->importCount;
                temp4 = i->importPrice;
                i->sellCount = j->sellCount;
                i->exportPrice = j->exportPrice;
                i->importCount = j->importCount;
                i->importPrice = j->importPrice;
                j->sellCount = temp1;
                j->exportPrice = temp2;
                j->importCount = temp3;
                j->importPrice = temp4;
            }
        }
    }
}

//按销售额高低显示
void orderSellmoney(struct good* head) {
    struct good* i, * j;
    for (i = head; i != NULL; i = i->next) {
        for (j = i->next; j != NULL; j = j->next) {
            if (i->sellCount * i->exportPrice < j->sellCount * j->exportPrice) {
                int temp1, temp3;
                float temp4, temp2;
                temp1 = i->sellCount;
                temp2 = i->exportPrice;
                temp3 = i->importCount;
                temp4 = i->importPrice;
                i->sellCount = j->sellCount;
                i->exportPrice = j->exportPrice;
                i->importCount = j->importCount;
                i->importPrice = j->importPrice;
                j->sellCount = temp1;
                j->exportPrice = temp2;
                j->importCount = temp3;
                j->importPrice = temp4;
            }
        }
    }
}

//菜单
void showMenu()
{
    printf("|-------------------|\n");
    printf("|请输入选项编号 0-5:|\n");
    printf("|--1--创建商品档案--|\n");
    printf("|--2--编辑商品信息--|\n");
    printf("|--3--统计销售情况--|\n");
    printf("|--4--查询商品信息--|\n");
    printf("|--5--显示商品信息--|\n");
    printf("|--0--  退出系统  --|\n");
    printf("|-------------------|\n");
}

//编辑商品
void editGood(struct good* head)
{
    while (1)
    {
        printf("|---------------------|\n");
        printf("|请输入选项编号  0-4:-|\n");
        printf("|--1-----添加新商品---|\n");
        printf("|--2----删除原有商品--|\n");
        printf("|--3--修改原有商品信息|\n");
        printf("|--4--------返回------|\n");
        printf("|--0------退出系统----|\n");
        printf("|---------------------|\n");
        int command;
        printf("输入指令:");
        scanf("%d", &command);
        switch (command)
        {
        case 1:
            createGood(&head); break;
        case 2:
            deleteGood(&head); break;
        case 3:
            changeGood(head); break;
        case 4:
            return;
        case 0:
            exit(0);
        default:
            printf("错误");
            break;
        }
    }
}

//查询商品信息
void findGood(struct good* head)
{
    while (1)
    {
        printf("|--------------------|\n");
        printf("|请输入选项编号  0-3:|\n");
        printf("|--1-----按品名查询--|\n");
        printf("|--2----按剩余数查询-|\n");
        printf("|--3--------返回-----|\n");
        printf("|--0--------退出-----|\n");
        printf("|--------------------|\n");
        int command;
        printf("输入指令");
        scanf("%d", &command);
        while (getchar() != '\n');
        switch (command)
        {
        case 1:
            findName(head); break;
        case 2:
            findCount(head); break;
        case 3:
            return;
        case 0:
            exit(0);
        default:
            printf("指令错误"); break;
        }
    }
}

//显示商品信息
void showGood(struct good* head)
{
    while (1)
    {
        printf("|------------------------|\n");
        printf("|--请输入选项编号  0-4:--|\n");
        printf("|--1-----按原来顺序显示--|\n");
        printf("|--2----按销售额高低显示-|\n");
        printf("|--3----按毛利高低显示---|\n");
        printf("|--4--------返回---------|\n");
        printf("|--0--------退出---------|\n");
        printf("|------------------------|\n");
        int command;
        printf("输入指令:");
        scanf("%d", &command);
        switch (command)
        {
        case 1:
            printList(head); break;
        case 2:
            orderSellmoney(head);
            printList(head);
            break;
        case 3:
            orderProfit(head);
            printList(head);
            break;
        case 4:
            return;
        case 0:
            exit(0);
        default:
            printf("指令错误!");
            break;
        }
    }
}

int main()
{
    struct good* head = NULL;
    while (1)
    {
        int command;
        showMenu();
        scanf("%d", &command);
        switch (command)
        {
        case 1:createGood(&head); break;
        case 2:editGood(head); break;
        case 3:statGood(head); break;
        case 4:findGood(head); break;
        case 5:showGood(head); break;
        case 0:freeList(head); exit(0);
        default:printf("指令错误!\n"); break;
        }
    }
}

  • 写回答

1条回答 默认 最新

  • 越重天 新星创作者: Java技术领域 2024-12-03 10:59
    关注

    本答案参考 多次询问 ChatGPT-3.5 后选择的最佳回答,若是满意,还请采纳,谢谢

    1. 问题分析
      • 在C语言中,当你删除链表的头节点时,如果之后还会使用已删除头节点的地址,这通常是因为没有正确地更新指针或者存在悬空指针的问题。
      • deleteGood函数中,虽然看起来逻辑上是正确地删除了头节点(当(*head)->number == key时),但是在后续的操作中可能存在问题。例如,当你打印链表(printList函数)时,可能没有正确处理指针的更新。
    2. 可能的错误点
      • printList函数中,它直接使用head指针进行遍历,没有考虑到如果头节点被删除后,head指针可能已经被更新。
      • 假设你删除了头节点,head应该指向新的头节点(原来的第二个节点),但是printList函数没有考虑到这种情况。例如,如果链表是1 -> 2 -> 3,你删除了节点1head应该指向2,但是printList函数没有重新评估head是否已经改变。
      • 另外,在deleteGood函数中,对于一些边界情况的处理可能不完全正确。例如,当删除最后一个节点时,代码中的逻辑可能存在问题。
    3. 修改建议
      • deleteGood函数中,确保正确处理所有的边界情况,包括删除头节点、中间节点和尾节点。
      • printList函数中,可以添加一个逻辑来检查head是否为NULL,并且在遍历链表时确保使用的是正确的head指针。
      • 例如,修改printList函数如下:
        //打印链表
        void printList(struct good* head)
        {
        struct good* current = head;
        if (current == NULL)
        {
           printf("内容为空,无法打印\n");
           return;
        }
        while (current!= NULL)
        {
           printf("编号%d 品名%s 进价%.2f 售价%.2f 进货量%d 销售量%d 销售额%.2f 剩余数%d 毛利%.2f\n", current->number,
               current->name, current->importPrice, current->exportPrice, current->importCount, current->sellCount,
               current->exportPrice * current->sellCount, current->importCount - current->sellCount, current->exportPrice * current->sellCount - current->importPrice * current->sellCount);
           current = current->next;
        }
        }
        
      • deleteGood函数中,对于删除尾节点的情况,可以修改为:
        else
        {
        struct good* temp = *head;
        struct good* current = NULL;
        while (temp->next!= NULL)
        {
           current = temp;
           temp = temp->next;
        }
        if (temp == NULL)
        {
           printf("找不到要删除商品!\n");
           return;
        }
        else if (temp->number == key)
        {
           if (current!= NULL)
           {
               current->next = NULL;
           }
           else
           {
               // 如果只有一个节点,删除后head应该为NULL
               *head = NULL;
           }
           free(temp);
           return;
        }
        }
        
    评论

报告相同问题?

问题事件

  • 创建了问题 12月3日