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
相关产品推荐
相关产品推荐

