C语言简易自动售货机源码与逻辑解析
通过结构体定义商品模型,结合循环结构处理多步投币与连续选购的逻辑,实现一个包含余额判断、库存扣减(计数)及自动找零功能的C语言控制台应用。
系统设计目标与规则
本示例构建了一个简易的自动化交易模型,旨在解决基础的资金管理与状态流转问题。系统设定了严格的交易边界条件:
- 商品池设置:预设编号 1-10 的十个商品,涵盖饮用水、碳酸饮料及茶饮,分为1元至4元不等价位。
- 资金管理:支持1元、2元、5元、10元纸币的累计注入,拒绝非法面额或非数字输入。
- 交互终止条件:用户可通过输入
-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);//输出余额
}
上述源码重点演示了如何在缺乏复杂对象管理的场景下,利用线性数组和基础控制流完成业务逻辑堆叠。虽然使用了较为原始的数据处理方式,但对于理解初学者阶段的变量作用域、指针算术及循环嵌套具有直观的教学价值。
执行结果观察
编译通过后,终端将依次呈现货币交互界面与控制台文本输出。典型的一次正常交易流程如下:
- 系统提示投入硬币,用户投入两张10元纸币(总和20)。
- 系统打印总计金额:
Total:20 yuan。 - 用户尝试选取商品编号(例如4号可乐,售价2元),系统确认扣除后,打印剩余:
There is still 18 yuan left。 - 若再次选取高价商品导致额度透支,控制台将拦截请求并打印:
Not enough money!。
局限性与优化方向
当前版本侧重于验证基本条件的可行性,存在几处明显的工程化短板,适合进阶学习参考:首先是采用硬编码映射而非哈希表查找商品,检索效率随规模扩大而降低;其次是未考虑重复按键导致的并发库存冲突模拟;此外,全局变量的广泛使用增加了代码耦合度。在实际生产级设计中,建议改用面向对象范式封装状态机,并通过配置文件分离资源定义。
以上就是C语言自动售货机程序的详细内容,更多关于C语言基础练习的资料请关注本站其它相关文章!本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













