C语言简易自动售货机源码与逻辑解析

小石头
小石头
发布时间:2026-10-16 | 7人浏览过
原创

通过结构体定义商品模型,结合循环结构处理多步投币与连续选购的逻辑,实现一个包含余额判断、库存扣减(计数)及自动找零功能的C语言控制台应用。

系统设计目标与规则

本示例构建了一个简易的自动化交易模型,旨在解决基础的资金管理与状态流转问题。系统设定了严格的交易边界条件:

  1. 商品池设置:预设编号 1-10 的十个商品,涵盖饮用水、碳酸饮料及茶饮,分为1元至4元不等价位。
  2. 资金管理:支持1元、2元、5元、10元纸币的累计注入,拒绝非法面额或非数字输入。
  3. 交互终止条件:用户可通过输入 -1 主动结束交易流程。

在核心业务流程中,系统遵循以下原则以保障逻辑闭环:若用户投入资金后未购买任何商品,全额退还;若在购物过程中发生余额不足以支付下一件商品的情况,则停止当前操作,退回剩余款项;即便在购货后仍有余额,一旦触发出库中断指令(如直接退出),系统将强制清算并退回账户内所有剩余资金。这种设计避免了资金滞留的风险。

环境准备

由于采用的是标准 ANSI C 语法,任何支持标准 C 编译器的环境均可运行该代码。建议使用 GCC、Clang 或在 Windows 下的 Visual Studio / Code::Blocks 等集成开发环境中进行调试。无需引入额外的第三方图形库。

第1步:定义数据结构

为了提高代码的可扩展性与可维护性,使用 typedef struct 创建 sell 结构体类型。每个实例包含整数型的唯一编号 num、字符数组形式的名称 name 以及整型价格 price。

第2步:初始化商品数据

在主函数启动阶段,通过数组初始化方式将所有商品参数硬编码至内存中。同时,定义一系列用于记录各编号商品购买次数的计数器变量(s1 至 s8),便于后续生成消费清单。

第3步:建立投币循环机制

利用 do...while 循环持续接收用户的货币投入。每次读取数值 c 后,首先校验其是否为合法面值(1、2、5、10)。若是合法面额,累加至全局总额 sum;若输入为 -1,立即跳出循环执行最终结算;否则报错提示无效输入。

第4步:商品筛选与动态余额校验

进入选购环节后,程序持续读取用户输入的编号 s:
- 若输入 -1 或余额低于选定商品价格,触发异常分支,中断选购循环。
- 对于有效编号,更新剩余可用资金 sum,并递增对应的购买统计量。

完整源码剖析

以下为整合后的核心实现代码,详细展示了上述步骤的具体写法:

#include<stdio.h>
#define N 10
int sum=0;
int sum1;
typedef struct sell{
	int num;
	char name[20];
	int price;
}sell;

void main()
{
	int i,c,s;
	int s1=0,s2=0,s3=0,s4=0,s5=0,s6=0,s7=0,s8=0;//记录商品购买数量
	sell se[N]={{1,"Table-water",1},{2,"Table-water",1},{3,"Table-water",1},{4,"Coca-Cola",2},{5,"Milk",2},
	{6,"Beer",3},{7,"Orange-Juice",3},{8,"Sprite",3},{9,"Oolong-Tea",4},{10,"Green-Tea",4}};  //售货机装入商品
	do {
		printf("Please put in coins:");
		scanf("%d",&c);  //投币
		if(c==1||c==2||c==5||c==10)
			sum=sum+c;
		else if(c==-1) break;
		else
			printf("error!\n");
	}
	while(c!=-1);
	printf("Total:%d yuan\n",sum);
	
	
	printf("Please select the goods serial number:");
	scanf("%d",&s);  //选择商品号
	se[-2].price =0;
	sum1=sum-se[s-1].price ;  //第一个选的商品超过投币数
	if(sum1<0||s==-1) printf("Not enough money!\n");
	else 		sum=sum1;
	
	while(sum>=0&&s!=-1) 	//什么都没买或者钱够但是不想买了
	{
		
		if(sum>=0){ 		    //钱花光了
			for(i=0;i<3;i++)
				if(s==se[i].num )
					s1++;
			for(i=3;i<N;i++)
			{
				if(s==se[i].num &&i==3) {s2++;break;}
				else if(s==se[i].num &&i==4) {s3++;break;}
				else if(s==se[i].num &&i==5) {s4++;break;}
				else if(s==se[i].num &&i==6) {s5++;break;}
				else if(s==se[i].num &&i==7) {s6++;break;}
				else if(s==se[i].num &&i==8) {s7++;break;}
				else if(s==se[i].num &&i==9) {s8++;break;}
				
				
			}
			printf("There is still %d yuan left\n",sum );
			
			printf("Please select the goods serial number:");
			scanf("%d",&s);
			sum1=sum-se[s-1].price ;   //最后一个商品钱不够
			if(sum1<0||s==-1) {printf("Not enough money!\n");break;}
			sum=sum1;
			
		}
		else printf("Not enough money!\n");
		
	}
	/*输出已购买商品名及数量*/
	if(s1!=0) 	printf("%s:%d\n",se[0].name ,s1);
	if(s2!=0) 	printf("%s:%d\n",se[3].name ,s2);
	if(s3!=0) 	printf("%s:%d\n",se[4].name ,s3);
	if(s4!=0) 	printf("%s:%d\n",se[5].name ,s4);
	if(s5!=0) 	printf("%s:%d\n",se[6].name ,s5);
	if(s6!=0) 	printf("%s:%d\n",se[7].name ,s6);
	if(s7!=0) 	printf("%s:%d\n",se[8].name ,s7);
	if(s8!=0) 	printf("%s:%d\n",se[9].name ,s8);
	if(sum>=0) 	printf("change:%d yuan\n",sum);//输出余额
	
}

上述源码重点演示了如何在缺乏复杂对象管理的场景下,利用线性数组和基础控制流完成业务逻辑堆叠。虽然使用了较为原始的数据处理方式,但对于理解初学者阶段的变量作用域、指针算术及循环嵌套具有直观的教学价值。

执行结果观察

编译通过后,终端将依次呈现货币交互界面与控制台文本输出。典型的一次正常交易流程如下:

  1. 系统提示投入硬币,用户投入两张10元纸币(总和20)。
  2. 系统打印总计金额:Total:20 yuan。
  3. 用户尝试选取商品编号(例如4号可乐,售价2元),系统确认扣除后,打印剩余:There is still 18 yuan left。
  4. 若再次选取高价商品导致额度透支,控制台将拦截请求并打印:Not enough money!。

局限性与优化方向

当前版本侧重于验证基本条件的可行性,存在几处明显的工程化短板,适合进阶学习参考:首先是采用硬编码映射而非哈希表查找商品,检索效率随规模扩大而降低;其次是未考虑重复按键导致的并发库存冲突模拟;此外,全局变量的广泛使用增加了代码耦合度。在实际生产级设计中,建议改用面向对象范式封装状态机,并通过配置文件分离资源定义。

以上就是C语言自动售货机程序的详细内容,更多关于C语言基础练习的资料请关注本站其它相关文章!
相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表