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

C语言联合体内结构体字段访问及工厂产品数据处理程序开发咨询

访问联合体内结构体字段的方法 + 工厂产品数据处理程序

先来说说如何访问联合体内的结构体字段:
联合(union)的核心特点是所有成员共享同一块内存空间,所以访问时必须先明确当前联合体实际存储的是哪个成员类型,之后直接用 . 操作符层层访问结构体里的字段就行。举个简单的示例框架:

// 进口产品专属结构体
typedef struct {
    char origin[50];
} ImportProduct;

// 本地产品专属结构体
typedef struct {
    char supplier[50];
    char phone[20];
} LocalProduct;

// 联合体存储两种产品的专属信息
typedef union {
    ImportProduct import;
    LocalProduct local;
} ProductExtra;

如果确定当前ProductExtra变量存的是进口产品数据,就用extra.import.origin访问产地;如果是本地产品,就用extra.local.supplier访问供应商名称。


下面是满足你需求的完整C程序,我把功能补全并做了优化:

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

// 枚举标记产品类型,用来判断该访问联合体的哪个成员
typedef enum {
    PRODUCT_IMPORT,
    PRODUCT_LOCAL
} ProductType;

// 进口产品专属信息
typedef struct {
    char origin[50];
} ImportDetails;

// 本地产品专属信息
typedef struct {
    char supplierName[50];
    char supplierPhone[20];
} LocalDetails;

// 联合体存储不同类型产品的专属数据
typedef union {
    ImportDetails import;
    LocalDetails local;
} ProductSpecific;

// 产品主结构体:公共属性 + 类型标记 + 专属信息联合体
typedef struct {
    char code[20];
    char description[100];
    char unitOfMeasure[10];
    float price;
    ProductType type;
    ProductSpecific specific;
} Product;

// 函数声明
void addProduct(Product *product);
void displayProduct(const Product *product);

int main() {
    Product product;
    int choice;

    do {
        printf("\n=== 工厂产品数据管理系统 ===\n");
        printf("1. 添加产品信息\n");
        printf("2. 显示当前产品信息\n");
        printf("3. 退出\n");
        printf("请输入选择: ");
        scanf("%d", &choice);
        getchar(); // 吃掉输入后的换行符,避免干扰后续字符串读取

        switch(choice) {
            case 1:
                addProduct(&product);
                break;
            case 2:
                displayProduct(&product);
                break;
            case 3:
                printf("程序退出中...\n");
                break;
            default:
                printf("无效选择,请重新输入!\n");
        }
    } while(choice != 3);

    return 0;
}

// 添加产品信息的函数
void addProduct(Product *product) {
    printf("\n--- 输入产品基础信息 ---\n");
    printf("产品编码: ");
    fgets(product->code, sizeof(product->code), stdin);
    product->code[strcspn(product->code, "\n")] = '\0'; // 去掉fgets读取的换行符

    printf("产品描述: ");
    fgets(product->description, sizeof(product->description), stdin);
    product->description[strcspn(product->description, "\n")] = '\0';

    printf("计量单位: ");
    fgets(product->unitOfMeasure, sizeof(product->unitOfMeasure), stdin);
    product->unitOfMeasure[strcspn(product->unitOfMeasure, "\n")] = '\0';

    printf("产品价格: ");
    scanf("%f", &product->price);
    getchar(); // 吃掉换行符

    printf("\n选择产品类型:\n");
    printf("1. 进口产品\n");
    printf("2. 本地采购产品\n");
    printf("请输入选择: ");
    int typeChoice;
    scanf("%d", &typeChoice);
    getchar();

    switch(typeChoice) {
        case 1:
            product->type = PRODUCT_IMPORT;
            printf("输入产品产地: ");
            fgets(product->specific.import.origin, sizeof(product->specific.import.origin), stdin);
            product->specific.import.origin[strcspn(product->specific.import.origin, "\n")] = '\0';
            break;
        case 2:
            product->type = PRODUCT_LOCAL;
            printf("输入供应商名称: ");
            fgets(product->specific.local.supplierName, sizeof(product->specific.local.supplierName), stdin);
            product->specific.local.supplierName[strcspn(product->specific.local.supplierName, "\n")] = '\0';

            printf("输入供应商电话: ");
            fgets(product->specific.local.supplierPhone, sizeof(product->specific.local.supplierPhone), stdin);
            product->specific.local.supplierPhone[strcspn(product->specific.local.supplierPhone, "\n")] = '\0';
            break;
        default:
            printf("无效类型,默认设为本地产品\n");
            product->type = PRODUCT_LOCAL;
            strcpy(product->specific.local.supplierName, "未知供应商");
            strcpy(product->specific.local.supplierPhone, "未知电话");
    }

    printf("产品信息添加完成!\n");
}

// 显示产品信息的函数
void displayProduct(const Product *product) {
    printf("\n--- 产品详细信息 ---\n");
    printf("编码: %s\n", product->code);
    printf("描述: %s\n", product->description);
    printf("计量单位: %s\n", product->unitOfMeasure);
    printf("价格: %.2f\n", product->price);

    if(product->type == PRODUCT_IMPORT) {
        printf("产品类型: 进口\n");
        printf("产地: %s\n", product->specific.import.origin);
    } else {
        printf("产品类型: 本地采购\n");
        printf("供应商名称: %s\n", product->specific.local.supplierName);
        printf("供应商电话: %s\n", product->specific.local.supplierPhone);
    }
}

程序核心说明:

  • 用ProductType枚举做类型标记,这是访问联合体成员的关键——只有明确当前产品类型,才能正确读取对应的专属字段,避免读取到错误内存区域的数据。
  • 主结构体Product整合了所有产品的公共属性,再通过联合体ProductSpecific存储不同类型产品的差异化信息,既节省内存,又逻辑清晰。
  • 做了输入处理优化:用fgets读取字符串避免缓冲区溢出,同时用strcspn去掉多余的换行符,保证数据整洁。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:51:03