You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C语言中动态分配结构体数组?实现可变长度购物列表

要实现无固定大小限制的购物列表,你需要把原来的固定数组改成动态内存分配,核心是用malloc/realloc来按需分配空间。以下是具体修改步骤和代码:

1. 更新头文件的结构体定义

把ShoppingList里的固定数组改成指针,这样才能动态分配内存:

#ifndef SHOPPING_LIST_H
#define SHOPPING_LIST_H

struct GroceryItem
{
    char productName[20];
    float amount;
    char unit[10];
};

struct ShoppingList
{
    int length;               // 当前已添加的条目数量
    struct GroceryItem* itemList;  // 指向动态分配的条目数组的指针
};

// 函数声明不变
void addItem(struct ShoppingList *list);
void printList(struct ShoppingList *list);
void editItem(struct ShoppingList *list);
void removeItem(struct ShoppingList *list);
void saveList(struct ShoppingList *list);
void loadList(struct ShoppingList* list);

#endif

2. 初始化购物列表(main函数)

初始化时要把动态数组指针设为NULL,表示当前没有分配内存,还要记得程序结束后释放内存避免泄漏:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include "ShoppingList.h"
#include<stdlib.h>

int main(void)
{
    struct ShoppingList shoppingList;
    shoppingList.length = 0;
    shoppingList.itemList = NULL; // 初始化空指针

    int option;

    do
    {
        printf("\n\nWelcome to the shopping list manager!\n");
        printf("=====================================\n\n");

        printf("1. Add an item\n");
        printf("2. Display the shopping list\n");
        printf("3. Remove an item\n");
        printf("4. Change an item\n");
        printf("5. Save list\n");
        printf("6. Load list\n");
        printf("7. Exit\n");

        printf("What do you want to do? ");
        scanf("%d", &option);

        switch (option)
        {
        case 1: addItem(&shoppingList); break;
        case 2: printList(&shoppingList); break;
        case 3: removeItem(&shoppingList); break;
        case 4: editItem(&shoppingList); break;
        case 5: saveList(&shoppingList); break;
        case 6: loadList(&shoppingList); break;
        case 7: break;
        default:
            printf("Please enter a number between 1 and 7\n");
        }
    } while (option != 7);

    // 释放动态分配的内存
    if (shoppingList.itemList != NULL)
    {
        free(shoppingList.itemList);
        shoppingList.itemList = NULL; // 置空防止野指针
    }

    return 0;
}

3. 修改addItem函数实现

每次添加条目时,用realloc动态扩容内存,同时要检查内存分配是否成功:

#define _CRT_SECURE_NO_WARNINGS
#include"ShoppingList.h"
#include<stdio.h>
#include<stdlib.h>

void addItem(struct ShoppingList* list)
{
    // 扩容内存:分配能容纳length+1个条目的空间
    struct GroceryItem* temp = realloc(list->itemList, sizeof(struct GroceryItem) * (list->length + 1));
    if (temp == NULL)
    {
        printf("内存分配失败,无法添加新条目!\n");
        return;
    }
    list->itemList = temp; // 分配成功后更新指针

    // 输入商品信息,逻辑和原来一致
    printf("Name for product: ");
    scanf("%s", list->itemList[list->length].productName);

    do
    {
        printf("Enter the amount: ");
        scanf("%f", &list->itemList[list->length].amount);

        if (list->itemList[list->length].amount <= 0.0)
        {
            printf("Input is invalid.\n");
        }

    } while (list->itemList[list->length].amount <= 0.0);

    printf("Enter unit of item: ");
    scanf("%s", list->itemList[list->length].unit);

    printf("%s was added to the shoppinglist.\n", list->itemList[list->length].productName);

    list->length++;
}

关键细节说明

  • realloc的用法:如果原指针是NULL(第一次添加时),realloc等价于malloc;如果原指针已有内存,会把原有数据复制到新的内存空间,然后释放旧空间。
  • 内存分配失败检查:realloc可能返回NULL(比如系统内存不足),必须判断,否则会导致程序崩溃。
  • 内存释放:动态分配的内存不会自动回收,必须用free手动释放,否则会造成内存泄漏。
  • 指针的数组式访问:动态分配的指针可以像普通数组一样用[下标]访问元素,C语言会自动处理指针偏移。

额外提示

  • 原代码中addItem函数有个错误:return 0;但函数返回类型是void,这个问题已经在修改后的代码中移除了。
  • 如果要支持带空格的商品名,后续可以把scanf("%s")换成fgets,注意处理换行符。

内容的提问来源于stack exchange,提问作者Hejhej12

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 16:10:32