Demo4—ATM提款机
要求:
1.用函数的方式实现ATM提款的基本操作
2.ATM提款机有如下功能:取款(100、200、500、其他)、查询、修改密码、退出。
函数的相关知识点:
1.为什么要用函数:将不同的功能模块化,抽离一些功能模块,一个函数只完成一个功能,让代码变得有价值,可以重复使用。
如:产生5个红球,从小到大排序,输出结果
2.如何定义一个函数
返回值 函数名称(参数,参数){
//代码块(函数体,完成一个功能)
}
int add(int a, int b){
int c = a + b;
return c;
}
3.如何调用一个函数
- 在main函数中调用上面定义的函数,调用者可以接收也可以不接收返回值,如果关心函数的返回值就接收,不关心则不接收。
- 这里需要接收做加法运算之后的值。所以新定义一个result变量接收返回值
int main(){
int result = add(1, 2);
return 0;
}
4.声明和定义顺序
4.1 边声明边定义
int add(int a, int b){//声明+定义
int c = a + b;
return c;
}
int main(){
int result = add(1, 2);//调用
return 0;
}
- 优点:不需要额外声明这个方法,main函数中可以直接使用
- 缺点:不易阅读,当有很多函数块时,main函数在最下面,可读性差。
4.2先声明,后实现(定义)
- 优点:可读性强
int add(int a, int b);//声明
int main(){
int result = add(1, 2);//调用
return 0;
}
int add(int a, int b){//定义
int c = a + b;
return c;
}
5.函数里面不能嵌套定义函数
如:
void test(){
int minus(int a,int b){
return a - b;
}
}//错误
6.return
- 有返回值时,如:return 1,返回值类型为int型。
- 没有返回值,如:return ,但是当某种条件发生就立刻终止函数。
分步编写代码:
1.程序运行起来要先输入密码,那就得定义一个密码,而且这个密码要在很多地方用到,如: 比较两个密码是否相同时,更改密码时,所以这个密码应该定义成全局变量。
int password = 123;
2.用户输入密码,写成一个函数。
- 输入密码不需要传值到函数中,所以参数列表中为空或者void,但是需要把用户输入的密码传出去,即要有返回值。
- 定义一个宏,用来赋予常量一个意义
#define kScuccess 1
#define kWrong 0
int inputPassword(void){
int inputpwd = 0;
int wrongTime = 0;
while (1) {
printf("请输入密码:");
scanf("%d", &inputpwd);
if (inputpwd == password) {
return kScuccess;
}else{
wrongTime ++;
if (wrongTime == 3) {
return kWrong;
}else{
printf("密码错误 ");
}
}
}
}
- main函数调用inputPassword函数:
int main(int argc, const char * argv[]) {
//用户输入密码
int result = inputPassword();
if (result == kWrong) {
//退出程序
exit(EXIT_SUCCESS);
}
return 0;
}
- 使用exit函数要先导入头文件:
#include <stdlib.h>
3.提示用户相应操作,即功能:取款、查询、修改密码、退出,取款时提醒用户操作:100、200、500、其他,提示用户操作有很多种方式,都是向终端输出相应的信息,所以,把提示用户操作写成一个函数,实现功能模块化。
- 提示用户相应操作,只是在终端显示几个选择,实现这个函数需要有选择的个数和选择的内容,所以需要传进去两个参数,一个参数是option[],一个是count;但是不需要返回值。
void show(char *option[], int count){
printf("******************\n");
for (int i = 0; i < count; i++) {
char *op = option[i];
printf("%d. %s\n", i + 1, op);
}
printf("******************\n");
}
- main函数中调用show函数:
int main(int argc, const char * argv[]) {
//用户输入密码
int result = inputPassword();
if (result == kWrong) {
//退出程序
exit(EXIT_SUCCESS);
}
while (1) {
//提示用户相应操作
char *alert[] = { "取款", "查询", "修改密码", "退出" };
show(alert, 4);
}
return 0;
}
4.用户选择1 2 3 4,检测用户输入的选择是否合法,用户选择要在多处被使用,所以写成一个函数。
- 要给函数中传一个值判断用户的选择是否合法,所以参数列表中要有一个参数max,而且函数最后要把用户输入的选择传出这个函数,所以也要有返回值。
int choice(int max){
int op = 0;
while (1) {
printf("请选择操作:");
scanf_s("%d", &op);
if (op > 0 && op <= max) {
return op;
}
else{
printf("输入错误 ");
}
}
}
- main函数中调用choice函数:
int main(int argc, const char * argv[]) {
//用户输入密码
int result = inputPassword();
if (result == kWrong) {
//退出程序
exit(EXIT_SUCCESS);
}
while (1) {
//提示用户相应操作
char *alert[] = { "取款", "查询", "修改密码", "退出" };
show(alert, 4);
//用户输入选择 1 2 3 4
int option = choice(4);
switch (option) {
case 1:
//取款
break;
case 2:
//查询
break;
case 3:
//修改密码
break;
case 4:
//退出
exit(EXIT_SUCCESS);
break;
default:
break;
}
}
return 0;
}
5.选择1—取款,写成一个函数,实现取款这个功能。
- 首先,要给用户显示可选金额,这就用到上面3中的show函数,参数中以字符串的形式给定可选金额和可选金额的数量即有几种选择;
- 第二,就是要检测用户输入是否合法,因为可供的选择是有限的,这就用到4中的choice函数,参数中传入可供选择的最大值;
- 第三,对用户的选择进行处理,可以定义一个变量outMoney用来记录用户选择的金额,然后比较余额和要取的金额数,判断能否取款成功,并向终端输出相应提示,如果取款成功输出当前余额,这时需要定义一个全局变量totalMoney并初始化;
- 第四,取款操作应该是可以重复操作也可以不重复操作,所以可以写一个函数用来让用户选择是否继续操作,如果用户不想继续操作,退出即可,如果要继续操作,则while循环会继续;
- 最后,取款函数不需要返回值和参数,因为取款后就没有后续了,不关心取了多少,要干什么,所以没有返回值。
void withdraw(void){
while (1) {
//提示用户选项
char *alert[] = { "100", "200", "500", "1000", "其他" };
show(alert, 5);
int op = choice(5);
int outMoney = 0; //记录需要取款的金额
switch (op) {
case 1:
outMoney = 100;
break;
case 2:
outMoney = 200;
break;
case 3:
outMoney = 500;
break;
case 4:
outMoney = 1000;
break;
case 5:
printf("请输入取款金额:");
scanf("%d", &outMoney);
break;
default:
break;
}
if (outMoney > totalMoney) {
//提示操作
printf("余额不足\n");
}
else{
totalMoney -= outMoney;
printf("取款成功 余额为:%d\n", totalMoney);
goOn();
}
}
}
- goOn函数
void goOn(void){
printf("是否继续操作 (y/n) ?:");
getchar();//接收回车键
char c = getchar();//接收用户输入的字符
if (c == 'n') {
exit(EXIT_SUCCESS);
}
}
- 在main函数中调用withdraw函数
case 1:
//取款
withdraw();
break;
6.选择2—查询
case 2:
//查询
printf("余额为:%d\n", totalMoney);
goOn();
break;
7.选择3—修改密码
- 不需要返回值,直接修改即可;
- 定义一个变量inputPwd用来接收原始密码;
- 新的密码可以直接用全局变量password接收,直接修改,并且要输入2次新的密码,如果2次一样才能修改成功。
void changePassword(void){
int inputPwd = 0;
while (1) {
printf("请输入原始密码:");
scanf("%d", &inputPwd);
if (inputPwd == password) {
printf("请输入新的密码:");
scanf("%d", &password);
printf("密码修改成功!\n");
return;
}
else{
printf("密码错误 ");
}
}
}
- 在main函数中调用changePassword函数
case 3:
//修改密码
changePassword();
goOn();
break;
最终代码
#include <stdio.h>
#include<stdlib.h>
//定义一个宏 用来赋予常量一个意义
#define kScuccess 1
#define kWrong 0
//定义全局变量 需要在多个地方呗使用
int password = 123;
int totalMoney = 1000;
//输入密码
int inputPassword(void);
//提示操作
void show(char *option[], int count);
//检测用户输入选项
int choice(int max);
//取款
void withdraw(void);
//提示是否继续操作
void goOn(void);
//修改密码
void changePassword(void);
int main(int argc, const char * argv[]) {
//用户输入密码
int result = inputPassword();
if (result == kWrong) {
//退出程序
exit(EXIT_SUCCESS);
}
while (1) {
//提示用户相应操作
char *alert[] = { "取款", "查询", "修改密码", "退出" };
show(alert, 4);
//用户输入选择 1 2 3 4
int option = choice(4);
switch (option) {
case 1:
//取款
withdraw();
break;
case 2:
//查询
printf("余额为:%d\n", totalMoney);
goOn();
break;
case 3:
//修改密码
changePassword();
goOn();
break;
case 4:
//
exit(EXIT_SUCCESS);
break;
default:
break;
}
}
return 0;
}
//输入密码
int inputPassword(void){
int inputpwd = 0;
int wrongTime = 0;
while (1) {
printf("请输入密码:");
scanf("%d", &inputpwd);
if (inputpwd == password) {
return kScuccess;
}
else{
wrongTime++;
if (wrongTime == 3) {
return kWrong;
}
else{
printf("密码错误 ");
}
}
}
}
//提示操作
void show(char *option[], int count){
printf("******************\n");
for (int i = 0; i < count; i++) {
char *op = option[i];
printf("%d. %s\n", i + 1, op);
}
printf("******************\n");
}
//检测用户输入选项
int choice(int max){
int op = 0;
while (1) {
printf("请选择操作:");
scanf("%d", &op);
if (op > 0 && op <= max) {
return op;
}
else{
printf("输入错误 ");
}
}
}
//取款
void withdraw(void){
while (1) {
//提示用户选项
char *alert[] = { "100", "200", "500", "1000", "其他" };
show(alert, 5);
int op = choice(5);
int outMoney = 0; //记录需要取款的金额
switch (op) {
case 1:
outMoney = 100;
break;
case 2:
outMoney = 200;
break;
case 3:
outMoney = 500;
break;
case 4:
outMoney = 1000;
break;
case 5:
printf("请输入取款金额:");
scanf("%d", &outMoney);
break;
default:
break;
}
if (outMoney > totalMoney) {
//提示操作
printf("余额不足\n");
}
else{
totalMoney -= outMoney;
printf("取款成功 余额为:%d\n", totalMoney);
goOn();
}
}
}
//提示用户是否继续操作
void goOn(void){
printf("是否继续操作 (y/n) ?:");
getchar();
char c = getchar();
if (c == 'n') {
exit(EXIT_SUCCESS);
}
}
//修改密码
void changePassword(void){
int inputPwd = 0;
while (1) {
printf("请输入原始密码:");
scanf("%d", &inputPwd);
if (inputPwd == password) {
printf("请输入新的密码:");
scanf("%d", &password);
printf("密码修改成功!\n");
return;
}
else{
printf("密码错误 ");
}
}
}
分文件管理程序
- .h文件:函数声明、宏定义、结构体变量声明、全局变量声明
- .c文件:函数的具体实现
- 条件编译指令
作用:防止头文件中的相互引用导致函数重复声明
#ifndef ATM_h
#define ATM_h
//代码块
#endif