C语言设计实验报告(第三次)
姓名:龚政
实验地点:家
实验时间:2020-3-25
实验项目:4.3.1箱子形状;4.3.2优惠政策;4.3.3计算月份天数;4.3.4自动售货机;4.3.5分析程序
实验目的与要求
正确使用C语言逻辑运算和关系运算
正确使用关系表达式和逻辑表达式
正确使用算术运算符和运算规则
if.else语句的使用方法
switeh-.case语句的使用方法
实验内容
实验练习:箱子形状
1.问题的简单描述:读入3个表示箱子长、宽、高的整数值,判断并输出该箱子是正方体还是长方体。
2.实验代码:
#include<stdio.h>
int main()
{
int l,w,h;
printf("请输入箱子的长,宽,高:\n");
scanf("%d%d%d",&l,&w,&h);
if(l==w&&w==h){
printf("该箱子是正方体。\n");
}else{
printf("该箱子是长方体。\n");
}
return 0;
}
3.问题分析:无
实验练习:优惠政策
1.问题的简单描述:编写程序实现如下功能:商店有打印纸( 18元本)墨盒( 132元/个)、光盘(4.5元/片)出售,商店进行优惠酬宾活动。具体规则如下:顾客购买商品的总额超过100 元,优惠5%;超过200元,优惠6%;超过300元,优惠7%;超过400元,优惠8%;超过500元,优惠10%。根据不同的购买量,计算应付货款。
2.实验代码
第一种写法:
#include<stdio.h>
int main()
{
int i,j,k;
double sum;
printf("请输入打印纸,墨盒,光盘的数量:");
scanf("%d,%d,%d",&i,&j,&k);
sum=18*i+132*j+4.5*k;
switch(sum>500){
case 1:sum*=0.9;break;
case 0:switch(sum>400){
case 1:sum*=0.92;break;
case 0:switch(sum>300){
case 1:sum*=0.93;break;
case 0:switch(sum>200){
case 1:sum*=0.94;break;
case 0:switch(sum>100){
case 1:sum*=0.95;break;
case 0:break;
}
}
}
}
}
printf("%lf",sum) ;
return 0;
}
第二种写法:
#include<stdio.h>
#include<limits.h>
main()
{
int a,b,c;
double x,y;
printf("请输入打印纸、墨盒、光盘的数量:");
scanf("%d,%d,%d",&a,&b,&c);
x=18*a+132*b+4.5*c;
switch((int)x)
{
case 500 ... INT_MAX:y=0.9*x;break;
case 400 ... 499:y=0.92*x;break;
case 300 ... 399:y=0.93*x;break;
case 200 ... 299:y=0.94*x;break;
case 100 ... 199:y=0.95*x;break;
default:printf("输入错误。");break;
}
if(x>0)
printf("应付款数=%.2f",y);
return 0;
}
3.问题分析:用switch
进行判断的时候,case
有两种情况0/1
,case
里面可以嵌套switch
和其他函数;第二种写法用到了头文件#include<limits.h>
来表达一个最大值INT_MAX
,用到100 ... 200
表示case
的范围,这是一个冷门的知识点
实验练习:计算月份天数
1问题的简单描述:输人某一年、月的数值,输出该月的天数。
2实验代码:
#include<stdio.h>
int main()
{
int year,month;
printf("please enter year and month:\n");
scanf("%d%d",&year,&month);
switch((year%4)==0&&(year%100)!=0||(year%400)==0){
case 1: if(month==2)
printf("%d年%d月有29天\n",year,month);
break;
default:if(month==2)
printf("%d年%d月有28天\n",year,month);
break;
}
switch(month==1||month==3||month==5||month==7||month==8||month==10||month==12){
case 1:printf("%d年%d月有30天\n",year,month);break;
case 0:switch(month){
case 2:break;
default:printf("%d年%d月有31天\n",year,month);break;
}
break;
}
return 0;
}
3问题分析:主要是对闰年的判断(year%4)==0&&(year%100)!=0||(year%400)==0
,然后就是对月份的判断:可以采取switch(month)-case
月份,但是代码会很长,不够简便,干脆就判断month==1||month==3||month==5||month==7||month==8||month==10||month==12
实验练习:自动售货机
1问题的简单描述:编写一个自动售货机的程序。该程序应具有如下功能:有两级菜单,一级菜 单是商品类型的选择;二级菜单是具体商品的选择(商品价格和品种可以自拟)。顾客先选择商品类型,然后选择具体商品,输入购买数量。自动售货机根据选择的商品和输人的数量,计算并显示所选商品的总金额
2实验代码:
#include<stdio.h>
int main()
{
int x,n,y;
float sum=0.0;
printf("请选择:1.日用品 2.文具 3.食品\n");
scanf("%d",&x);
switch(x)
{
case 1: printf("请选择:1.牙刷(3.5元/支) 2.牙膏(6.2元/支)\n");
printf(" 3.肥皂(2元/块) 4.毛巾(8.6元/条)\n");
scanf("%d",&y);
printf("数量?");
scanf("%d",&n);
switch(y)
{
case 1:sum=3.5*n;break;
case 2:sum=6.2*n;break;
case 3:sum=2*n;break;
case 4:sum=8.6*n;break;
}
break;
case 2: printf("请选择:1.笔(3元/支) 2.笔记本(1.2/支)\n");
printf(" 3.文件夹(12元/块) 4.文具盒(8.6元/条)\n");
scanf("%d",&y);
printf("数量?");
scanf("%d",&n);
switch(y)
{
case 1:sum=3*n;break;
case 2:sum=1.2*n;break;
case 3:sum=12*n;break;
case 4:sum=8.6*n;break;
}
break;
case 3: printf("请选择:1.白糖(3.6元/支) 2.盐(1/支)\n");
printf(" 3.饼(2元/块) 4.方便面(3.6元/条)\n");
scanf("%d",&y);
printf("数量?");
scanf("%d",&n);
switch(y)
{
case 1:sum=3.6*n;break;
case 2:sum=1*n;break;
case 3:sum=2*n;break;
case 4:sum=3.6*n;break;
}
break;
}
printf("总计:%.2f元\n",sum);
return 0;
}
3问题分析:switch-case
中case
要输入多个语句不用加{}
,直接在后面输入就行了,记得最后加一个break;
实验练习:分析程序
1.问题的简单描述:对程序进行分析
2.实验代码:
#include<stdio.h>
int main()
{
double x=1000/3.0;
double y=x-333.0;
double z=3*y-1.0;
printf("x=%lf\n",x);
printf("y=%lf\n",y);
printf("z=%lf\n",z);
if(z==0) printf("z==0\n");
else printf("z不等于0\n");
return 0;
}
3.问题分析:按理说z=0
,但是实际上不等于零,可以用%.63lf
检验xyz
的值,你就会发现其实浮点数不是一个你想要的数,而是一个近似值,也就是说浮点数会取最近的一个值作为变量的值
项目实训:计算器的实现
初代版本zero
2020.3.20 9:50
版本特性
单纯循环利用加减乘除计算
设计思路
利用switch-case
判断输入字符为+``-``*``/
对应做出计算
流程图
设计过程中遇到的问题及改进的方法
对变量进行定义的是double
,对应的scanf("%lf")
,而不是%f
;
代码:
#include<stdio.h>
int main()
{
double tot,i,j;
char ch;
printf("请输入第一个数:") ;
scanf("%lf",&i);
printf("请输入运算符;");
scanf("%c",&ch);
printf("请输入第二个数:") ;
scanf("%lf",&j);
if(ch=='+') {
tot=i+j;
}else if(ch=='-'){
tot=i-j;
}else if(ch=='*'){
tot=i*j;
}else if(ch=='/'){
tot=i/j;
}
printf("%f",tot);
return 0;
}
第一版
2020.3.20 10:10
版本特性
简化代码,语句合并;可以进行循环输入
设计思路
zero版本无法循环输入,第一代加入了循环结构以便输入
流程图
设计过程中遇到的问题及改进的方法
1.循环输入的格式:先输入第一个数,然后循环计算之后的,这样可以叠加运算;
2.循环选择哪种写法:用for循环可以合并一些代码;
代码:
#include<stdio.h>
int main()
{
int sum,j;
printf("请输入第1个数:") ;
scanf("%d",&sum);
char ch;
int t;
for(t=2;getchar()!='=';t++){
printf("请输入运算符以及第%d个数:",t);
ch=getchar();
scanf("%d",&j);
switch(ch){
case'+':sum+=j;break;
case'-':sum-=j;break;
case'*':sum*=j;break;
case'/':sum/=j;break;
}
printf("%d\n",sum);
}
printf("%d",sum);
return 0;
}
第二版
2020.3.20 14:36
版本特性
加入了菜单,但是选项只可用两个
优化了代码界面,可以刷新屏幕
设计思路
第一版计算机功能太过于单调,加入了菜单功能,可以实现多组数据计算(非叠加运算);可以退出程序
流程图
设计过程中遇到的问题及改进的方法:
1.如何判断用户输入的按键:用到#include<conio.h>
中的getch();
2.如何循环运行这个程序直到用户退出:用到do while(1);
无限循环
3.如何优化界面:用到#include<windows.h>
中的system("cls")
,在每一次完成程序时清除屏幕内容,让布局简单
代码
#include<stdio.h>
#include <conio.h>//用于getch()读取用户输入的按键
#include<windows.h>//用于清理屏幕
int main()
{
//多次运算多组数据
do{
//菜单
printf("---------------------菜单--------------------\n") ;
printf("↑:加减乘除 \n") ;
printf("Esc:退出 \n") ;
printf("Home:设置 \n") ;
printf("---------------------------------------------\n") ;
//判断用户输入选项
char userput;
userput=getch();//第一次调取 ,之后的if是第二次调取,实际值
//加减乘除运算
if(userput==72)
{
printf("---------------------------------------------\n");
printf("| 加减乘除模式 |\n");
printf("---------------------------------------------\n");
int sum,j;
printf("请输入第1个数:") ;
scanf("%d",&sum);
char ch;
int t;
//多次输入计算单组数据
for(t=2;getchar()!='=';t++){//t的作用是为下面提示输入第几个数
//获取用户输入的运算符以及第几个数
printf("请输入运算符及第%d个数(如:+8,如果结束运算请输入==):",t);
ch=getchar();
scanf("%d",&j);
//判断运算符,做出对应运算
switch(ch){
case'+':sum+=j;break;
case'-':sum-=j;break;
case'*':sum*=j;break;
case'/':sum/=j;break;
}
printf("本次计算结果=%d\n",sum);
}
//printf("最终结果=%d",sum);
}
//退出程序
else if(userput==27)
{
printf("---------------------------------------------\n");
printf("| 退出程序 |\n");
printf("---------------------------------------------\n");
break;
}
//为了让布局美观,每次算完之后清空屏幕 ,用到了头文件#include<windows.h>
system("cls") ;
}while(1);
return 0;
}
第三版
2020.3.20 15:05
版本特性
完善设置选项卡:保留小数;刷新屏幕
设计思路
完善设置选项卡,可以执行操作:保留几位小数;是否关闭屏幕刷新
流程图
设计过程中遇到的问题及改进的方法
1.关闭屏幕刷新要如何实现:两块区域,第一块判断是否要关闭,第二块执行关闭操作
2.保留几位小数如何实现:%.*lf
中的*
表示一个变量的值,也就是保留几位小数的变量
代码
#include<stdio.h>
#include <conio.h>//用于getch()读取用户输入的按键
#include<windows.h>//用于清理屏幕
int main()
{
int set;//用于设置选项卡,放在外面的原因是让每一次循环都可以用到,而不改变set的值,以免影响下一次循环
int point=2;//用于设置选项卡,对于输出的数保留n位小数 ,默认保留两位小数
//多次运算多组数据
do{
//菜单
printf("---------------------菜单--------------------\n") ;
printf("↑:加减乘除 \n") ;
printf("Esc:退出 \n") ;
printf("Home:设置 \n") ;
printf("---------------------------------------------\n") ;
//判断用户输入选项
char userput;
userput=getch();//第一次调取 ,之后的if是第二次调取,实际值
//加减乘除运算
if(userput==72)//72表示用户输入上箭头
{
printf("---------------------------------------------\n");
printf("| 加减乘除模式 |\n");
printf("---------------------------------------------\n");
double sum,j;
printf("请输入第1个数:") ;
scanf("%lf",&sum);
char ch;
int t;
//多次输入计算单组数据
for(t=2;getchar()!='=';t++){//t的作用是为下面提示输入第几个数
//获取用户输入的运算符以及第几个数
printf("请输入运算符及第%d个数(如:+8,以==退出):",t);
ch=getchar();
scanf("%lf",&j);
//判断运算符,做出对应运算
switch(ch){
case'+':sum+=j;break;
case'-':sum-=j;break;
case'*':sum*=j;break;
case'/':sum/=j;break;
}
printf("本次计算结果=%.*lf\n",point,sum);
}
}
//退出程序
else if(userput==27)
{
printf("---------------------------------------------\n");
printf("| 退出程序 |\n");
printf("---------------------------------------------\n");
break;
}
//设置选项卡
//判断区
else if(userput==71)
{
printf("---------------------------------------------\n");
printf("| 设置 |\n");
printf("|1.刷新屏幕 |\n");
printf("|2.保留小数 |\n");
printf("---------------------------------------------\n");
int setin;
char setchoose;
printf("请输入数字以进入选项:") ;
scanf("%d",&setin);
//1.刷新屏幕
if(setin==1)
{
printf("是否关闭刷新屏幕[y/n]:");
scanf("%c",&setchoose);
if(setchoose=='y'){
set=1;
} else{
set=0;
}
}
//2.保留小数
if(setin==2)
{
printf("你希望保留几位小数?:");
scanf("%d",&point);//这里不需要经过执行区
}
}
//执行区
if(set==1)//选择的是弄yes
{
}
else//选择的是no
{
//为了让布局美观,每次算完之后清空屏幕 ,用到了头文件#include<windows.h>
system("cls") ;
}
}while(1);
return 0;
}
第四版
2020.3.20 20:04
版本特性
优化了加减乘除(可以进行小数运算,多亏了
%lf
);
加入了十进制转换其他进制模式;
设计思路
在原计算器的基础上加入十进制转换其他进制模式
流程图
流程图太复杂了,作者已经狗带
设计过程中遇到的问题及改进的方法
1.如何将十进制转化为其他进制
①转化为八进制,十六进制:很简单就只要%d %o %x输出就行了(分别对应十进制,八进制,十六进制)
②转化为二进制:这个就复杂一点,需要除二取余,倒序相加,因此就要用到循环,每一次都要除以二,取到余数,并且最后的结果是倒序;相当于判断一个数是几位数,并且逆序拆解这个数
代码
#include<stdio.h>
#include <conio.h>//用于getch()读取用户输入的按键
#include<windows.h>//用于清理屏幕
int main()
{
int set;//用于设置选项卡,放在外面的原因是让每一次循环都可以用到,而不改变set的值,以免影响下一次循环
int point=2;//用于设置选项卡,对于输出的数保留n位小数 ,默认保留两位小数
double i,j,k,sum,num,left;//参与计算:加减乘除,进制转换
int ip,jp,kp,sump,nump,leftp;//参与计算:加减乘除,进制转换
//多次运算多组数据
do{
//菜单
printf("---------------------菜单--------------------\n") ;
printf("↑:加减乘除 \n") ;
printf("↓:进制转换 \n") ;
printf("Esc:退出 \n") ;
printf("Home:设置 \n") ;
printf("---------------------------------------------\n") ;
//判断用户输入选项
char userput;
userput=getch();//第一次调取 ,之后的if是第二次调取,实际值
//加减乘除运算
if(userput==72)//72表示用户输入上箭头
{
printf("---------------------------------------------\n");
printf("| 加减乘除模式 |\n");
printf("---------------------------------------------\n");
double sum;
printf("请输入第1个数:") ;
scanf("%lf",&sum);
char ch;
int t;
//多次输入计算单组数据
for(t=2;getchar()!='=';t++){//t的作用是为下面提示输入第几个数
//获取用户输入的运算符以及第几个数
printf("请输入运算符及第%d个数(如:+8,以==退出):",t);
ch=getchar();
scanf("%lf",&j);
//判断运算符,做出对应运算
switch(ch){
case'+':sum+=j;break;
case'-':sum-=j;break;
case'*':sum*=j;break;
case'/':sum/=j;break;
}
printf("%lf%c%lf=%.*lf\n",sum,ch,j,point,sum);
}
}
//进制转换
else if(userput==80)
{
printf("---------------------------------------------\n");
printf("| 进制转换模式 |\n");
printf("---------------------------------------------\n");
do{
printf("请输入你要转换的十进制整数:");
scanf("%d",&ip);
printf("你想转换成___进制:");
scanf("%d",&jp);
//处理数据
kp=ip;//暂存IP的数值,下面要对他分解
sump=0;//初始总和=0
for(nump=1;ip>0;nump*=10) {
leftp=ip%jp;//取余
ip/=jp;//取整
sump+=nump*leftp;//倒序相加
}
ip=kp;//IP换回原来值
printf("%d的%d进制数是%d\n",ip,jp,sump);
printf("按下任意键继续(Esc退出)\n");//借用退出程序的功能
userput=getch();
}while(userput!=27);
}
//退出程序
else if(userput==27)
{
printf("---------------------------------------------\n");
printf("| 退出程序 |\n");
printf("---------------------------------------------\n");
break;
}
//设置选项卡
//判断区
else if(userput==71)
{
printf("---------------------------------------------\n");
printf("| 设置 |\n");
printf("|1.刷新屏幕 |\n");
printf("|2.保留小数 |\n");
printf("---------------------------------------------\n");
int setin;
char setchoose;
printf("请输入数字以进入选项:") ;
scanf("%d",&setin);
//1.刷新屏幕
if(setin==1)
{
printf("是否关闭刷新屏幕[y/n]:");
scanf(" %c",&setchoose);//考虑到scanf的读取,上一个scanf结尾是\n,在进行这个scanf的时候把\n算在%c里面,一定要加一个空格
if(setchoose=='y'){
set=1;
} else{
set=0;
}
}
//2.保留小数
else if(setin==2)
{
printf("你希望保留几位小数?:");
scanf("%d",&point);//这里不需要经过执行区
}
}
//执行区
if(set==1)//选择的是弄yes
{
printf("修改成功\n");
}
else//选择的是no
{
//为了让布局美观,每次算完之后清空屏幕 ,用到了头文件#include<windows.h>
system("cls") ;
}
}while(1);
return 0;
}
第五版
时间记不清了>.<
版本特性
新加选项卡:进制转换(目前只支持十进制转其他进制)
优化输入函数:可以判断用户输入是否合法
修复部分bug:在注释都有讲到
设计思路
判断用户输入是否合法,优化程序运行
流程图
由于流程图实在是太复杂,作者画出来的话恐怕已经秃头
了!!!
设计过程中遇到的问题及改进的方法
1.如何判断用户是否合法?
①这里需要提到缓冲区,如果用户输入的格式超过长度,比如要求1+1
,用户输入1+1+2
,这时候运算是正常的,但是缓冲区还剩下+2
没有被scanf
拿走,在下一次scanf
的时候,这个+2
就会被拿走而不读取用户的输入了,这时候就很可能造成程序运行错误;
有一个代码while(getchar()!='\n');
可以清空缓存区,原理就是getchar
每次会拿走缓冲区一个字符,只要不赋值给其他变量,getchar()
可以一直拿走缓冲区字符,而且可以再while
循环里面运行
②如果要求输入数字,而用户输入字符如+,这时候也会影响结果。这时候就要判断用户输入是否符合要求
第一种用scanf(“%d”,&X)
是否=1
判断输入的是否是一个整型,原理就是scanf
会返回值,当正确输入一个变量就会返回1,两个变量就是2
第二种就是用isdigit
判断输入是否是数字,关于判断是否为字符也有其他代码
第三种就是再常规不过的直接判断x=1
每种方法各有优劣,看你的代码适合哪一种判断
代码
#include<stdio.h>
#include <conio.h>//用于getch()读取用户输入的按键
#include<windows.h>//用于清理屏幕
int main()
{
int set;//用于设置选项卡,放在外面的原因是让每一次循环都可以用到,而不改变set的值,以免影响下一次循环
int point=2;//用于设置选项卡,对于输出的数保留n位小数 ,默认保留两位小数
double i,j,k,sum,num,left;//参与计算:加减乘除,进制转换
int ip,jp,kp,sump,nump,leftp;//参与计算:加减乘除,进制转换
//多次运算多组数据
do{
//菜单
printf("---------------------菜单--------------------\n") ;
printf("↑:加减乘除 \n") ;
printf("↓:进制转换 \n") ;
printf("Home:设置 \n") ;
printf("Esc:退出程序 \n") ;
printf("---------------------------------------------\n") ;
//判断用户输入选项
printf("请按下按键以进入选项:\n");
char userput,userput0;
userput0=getch();//第一次调取
userput=getch();//第二次调用,这次是实际值
//加减乘除运算
if(userput==72)//72表示用户输入上箭头
{
printf("---------------------------------------------\n");
printf("| 加减乘除模式 |\n");
printf("---------------------------------------------\n");
double sum;
printf("请输入第1个数:");
while(scanf("%lf",&sum)!=1) {//在while里面的scanf可以执行,而且scanf是自带返回值的,正确输入一个变量可以返回1
printf("非法输入,请重新输入\n");
while(getchar()!='\n');//当用户输入一个错误的格式,getchar()的作用就是拿走缓冲区内的第一个字符,这样写可以清空缓冲区,以免ch=getchar()出错
}
char ch;
int t;
num=sum;//num的作用:暂存sum的值为了服务最后输出的时候,运算表达式是正确的
//多次输入计算单组数据
for(t=2;getchar()!='=';t++){//t的作用是为下面提示输入第几个数
while(1) {
printf("请输入运算符及第%d个数(如:+8,以==退出):",t);
ch=getchar();
scanf("%lf",&j);
if(ch='='){
break;
}
else if(scanf("%lf",&j)!=1||(ch!='+'&&ch!='-'&&ch!='*'&&ch!='/'&&ch!='='))
{
printf("非法输入,请重新输入\n");
while(getchar()!='\n');//清空缓存区
}
}
//判断运算符,做出对应运算
switch(ch){
case'+':sum+=j;break;
case'-':sum-=j;break;
case'*':sum*=j;break;
case'/':sum/=j;break;
}
printf("%lf%c%lf=%.*lf\n",num,ch,j,point,sum);
num=sum;//输出计算结果的时候显示的是正确值__*__=__
}
}
//进制转换
else if(userput==80)
{
do{
printf("---------------------------------------------\n");
printf("| 进制转换模式 |\n");
printf("|1.十进制转为其他进制 |\n");
printf("|2.其他进制转为十进制 |\n");
printf("|3.二进制转为其他进制 |\n");
printf("---------------------------------------------\n");
printf("请选择序号以进入选项:") ;
while(scanf("%d",&userput)!=1&&userput<1&&userput>4) {
printf("非法输入,请重新输入\n");
while(getchar()!='\n');//清空缓存区
}
if(userput==1)
{
do{
printf("请输入你要转换的十进制整数:");
while(scanf("%d",&ip)!=1) {
printf("非法输入,请重新输入\n");
while(getchar()!='\n');//清空缓存区
}
printf("你想转换成___进制:");
while(scanf("%d",&jp)!=1) {
printf("非法输入,请重新输入\n");
while(getchar()!='\n');//清空缓存区
}
//处理数据
kp=ip;//暂存IP的数值,下面要对他分解
sump=0;//初始总和=0
for(nump=1;ip>0;nump*=10) {
leftp=ip%jp;//取余
ip/=jp;//取整
sump+=nump*leftp;//倒序相加
}
ip=kp;//IP换回原来值
printf("%d的%d进制数是%d\n",ip,jp,sump);
printf("按下任意键继续(Esc回到上一级菜单)\n");//借用退出程序的功能
userput=getch();
}while(userput!=27);
}
else if(userput==2)
{
printf("转换数类型是八进制/十六进制[8/16]");
}
printf("你现在处在进制转换模式") ;
printf("按下任意键继续(Esc回到主菜单)\n");//借用退出程序的功能
userput=getch();
}while(userput!=27) ;
}
//退出程序
else if(userput==27)
{
printf("---------------------------------------------\n");
printf("| 退出程序 |\n");
printf("---------------------------------------------\n");
break;
}
//设置选项卡
//判断区
else if(userput==71)
{
printf("---------------------------------------------\n");
printf("| 设置 |\n");
printf("|1.刷新屏幕 |\n");
printf("|2.保留小数 |\n");
printf("---------------------------------------------\n");
char setchoose;
printf("请输入数字以进入选项:") ;
while(scanf("%c",&userput)!=1) {
printf("非法输入,请重新输入\n");
while(getchar()!='\n');//清空缓存区
}
//1.刷新屏幕
if(userput=='1')
{
printf("是否关闭刷新屏幕[y/n]:");
scanf(" %c",&setchoose);//考虑到scanf的读取,上一个scanf结尾是\n,在进行这个scanf的时候把\n算在%c里面,一定要加一个空格
if(setchoose=='y'){
set=1;
printf("修改成功\n");
} else{
set=0;
}
}
//2.保留小数
else if(userput=='2')
{
printf("你希望保留几位小数?:");
scanf("%d",&point);//这里不需要经过执行区,因为有默认保留几位小数,要必须经过这里才能修改,放在执行区的话就会每次都修改
}
}
//按下不存在按键
else{
printf("请按下正确的按键,回车键继续");
while(getchar()!='\n');
}
//设置选项卡执行区
if(set==1)//选择的是弄yes
{
printf("***************以上是历史内容****************\n");
}
else//选择的是no ,或者不选
{
//为了让布局美观,每次算完之后清空屏幕 ,用到了头文件#include<windows.h>
system("cls") ;
}
}while(1);
return 0;
}
第六版
2020.3.21 12:30
版本特性
修复了一些bug:比如加减乘除模式中判断用户输入是否合法,会出现判断错误
完善了进制转换,同时在上一代的基础上优化了进制转换界面,和操作,提高用户体验
预告
之后版本可能会出现专业计算:包括数学函数的计算,函数的描绘
设计思路
流程图
设计过程中遇到的问题及改进的方法
代码
#include<stdio.h>
#include <conio.h>//用于getch()读取用户输入的按键
#include<windows.h>//用于清理屏幕
#include<math.h>
int main()
{
int set;//用于设置选项卡,放在外面的原因是让每一次循环都可以用到,而不改变set的值,以免影响下一次循环
int point=2;//用于设置选项卡,对于输出的数保留n位小数 ,默认保留两位小数
double i,j,k,sum,num,left;//参与计算:加减乘除,进制转换
int ip,jp,kp,sump,nump,leftp;//参与计算:加减乘除,进制转换
//多次执行程序
do{
//菜单
printf("---------------------菜单--------------------\n") ;
printf("↑:加减乘除 \n") ;
printf("↓:进制转换 \n") ;
printf("←:专业运算 \n") ;
printf("Home:设置 \n") ;
printf("Esc:退出程序 \n") ;
printf("---------------------------------------------\n") ;
//判断用户输入选项
printf("请按下按键以进入选项:\n");
char userput,userput0;
userput0=getch();//第一次调取
userput=getch();//第二次调用,这次是实际值
//加减乘除运算
if(userput==72)//72表示用户输入上箭头
{
printf("---------------------------------------------\n");
printf("| 加减乘除模式 |\n");
printf("---------------------------------------------\n");
double sum;
printf("请输入第1个数:");
while(scanf("%lf",&sum)!=1) {//在while里面的scanf可以执行,而且scanf是自带返回值的,正确输入一个变量可以返回1
printf("非法输入,请重新输入\n");
while(getchar()!='\n');//当用户输入一个错误的格式,getchar()的作用就是拿走缓冲区内的第一个字符,这样写可以清空缓冲区,以免ch=getchar()出错
}
char ch;
int t;
num=sum;//num的作用:暂存sum的值为了服务最后输出的时候,运算表达式是正确的
//多次输入计算单组数据
for(t=2;getchar()!='=';t++){//t的作用是为下面提示输入第几个数
while(1) {
printf("请输入运算符及第%d个数(如:+8,以==退出):",t);
ch=getchar();
//scanf("%lf",&j);
if(ch=='=')
{
printf("即将退出.............\n");
system("pause");
break;
}
else if(scanf("%lf",&j)!=1||(ch!='+'&&ch!='-'&&ch!='*'&&ch!='/'&&ch!='='))
{
printf("非法输入,请重新输入\n");
while(getchar()!='\n');//清空缓存区
}else if(j==0&&ch=='/') {
printf("除数不为零,请重新输入\n");
while(getchar()!='\n');
}else break;
}
//判断运算符,做出对应运算
switch(ch){
case'+':sum+=j;break;
case'-':sum-=j;break;
case'*':sum*=j;break;
case'/':sum/=j;break;
}
printf("%lf%c%lf=%.*lf\n",num,ch,j,point,sum);
num=sum;//输出计算结果的时候显示的是正确值__*__=__
}
}
//进制转换
else if(userput==80)
{
do{
printf("---------------------------------------------\n");
printf("| 进制转换模式 |\n");
printf("|1.二进制模式 |\n");
printf("|2.八进制模式 |\n");
printf("|3.十进制模式 |\n");
printf("|4.十六进制模式 |\n");
printf("---------------------------------------------\n");
//改进
printf("请输入序号以进入模式:");
while(scanf("%d",&userput)!=1) {
printf("非法输入,请重新输入\n");
while(getchar()!='\n');//清空缓存区
}
//十进制转其他进制
if(userput==3)
{
do{
printf("---------------------------------------------\n");
printf("| 十进制模式 |\n");
printf("---------------------------------------------\n");
printf("请输入十进制整数:");
while(scanf("%d",&ip)!=1) {
printf("非法输入,请重新输入\n");
while(getchar()!='\n');//清空缓存区
}
//处理其他进制转化为二进制数
kp=ip;//暂存IP的数值,下面要对他分解
sump=0;//初始总和=0
for(nump=1;ip>0;nump*=10) {
leftp=ip%2;//取余
ip/=2;//取整
sump+=nump*leftp;//倒序相加
}
ip=kp;//IP换回原来用户输入值
printf("十进制数%d的2进制数是%d\n",ip,sump);
printf("十进制数%d的8进制数是%o\n",ip,ip);
printf("十进制数%d的16进制数是%x\n",ip,ip);
printf("按下任意键继续转换(Esc回到上一级菜单)\n");//借用退出程序的功能
userput0=getch();
}while(userput0!=27);
}
//八进制转其他进制
else if(userput==2)
{
printf("---------------------------------------------\n");
printf("| 八进制模式 |\n");
printf("---------------------------------------------\n");
printf("请输入八进制数:");
scanf("%d",&ip);
//处理其他进制转化为二进制数
kp=ip;//暂存IP的数值,下面要对他分解
sump=0;//初始总和=0
for(nump=1;ip>0;nump*=10) {
leftp=ip%2;//取余
ip/=2;//取整
sump+=nump*leftp;//倒序相加
}
ip=kp;//IP换回原来用户输入值
printf("八进制数%o的二进制数是%d\n",ip,sump);
printf("八进制数%o的十进制数是%d\n",ip,ip);
printf("八进制数%o的十六进制数是%x\n",ip,ip);
}
else if(userput==4)
{
printf("---------------------------------------------\n");
printf("| 十六进制模式 |\n");
printf("---------------------------------------------\n");
printf("请输入十六进制数:");
scanf("%d",&ip);
//处理其他进制转化为二进制数
kp=ip;//暂存IP的数值,下面要对他分解
sump=0;//初始总和=0
for(nump=1;ip>0;nump*=10) {
leftp=ip%2;//取余
ip/=2;//取整
sump+=nump*leftp;//倒序相加
}
ip=kp;//IP换回原来用户输入值
printf("十六进制数%x的二进制数是%d\n",ip,sump);
printf("十六进制数%x的十进制数是%d\n",ip,ip);
printf("十六进制数%x的十六进制数是%x\n",ip,ip);
}
else if(userput==1)
{
printf("---------------------------------------------\n");
printf("| 二进制模式 |\n");
printf("---------------------------------------------\n");
do{
printf("请输入二进制数:") ;
scanf("%d",&ip) ;
//二进制转为十进制
kp=ip;
sump=0;
for(nump=0;ip>0;nump++){
leftp=ip%10;// 得到最后一位
ip/=10;//去掉最后一位
if(leftp!=1&&leftp!=0) {
printf("非法二进制,请重新操作!\n");
break;
}else if(leftp==1){
sump+=pow(2,nump);
}else if(leftp==0){
}
}
}while(ip>0);
printf("二进制数%d的八进制数是%o\n",kp,sump);
printf("二进制数%d的十进制数是%d\n",sump,sump);
printf("二进制数%d的十六进制数是%x\n",sump,sump);
}
printf("你现在处在进制转换模式") ;
printf("按下任意键继续(Esc回到主菜单)\n");//借用退出程序的功能
userput0=getch();
}while(userput0!=27) ;
}
//退出程序
else if(userput==27)
{
printf("---------------------------------------------\n");
printf("| 退出程序 |\n");
printf("---------------------------------------------\n");
break;
}
//设置选项卡
//判断区
else if(userput==71)
{
printf("---------------------------------------------\n");
printf("| 设置 |\n");
printf("|1.刷新屏幕 |\n");
printf("|2.保留小数 |\n");
printf("---------------------------------------------\n");
char setchoose;
printf("请输入数字以进入选项:") ;
while(scanf("%c",&userput)!=1) {
printf("非法输入,请重新输入\n");
while(getchar()!='\n');//清空缓存区
}
//1.刷新屏幕
if(userput=='1')
{
printf("是否关闭刷新屏幕[y/n]:");
scanf(" %c",&setchoose);//考虑到scanf的读取,上一个scanf结尾是\n,在进行这个scanf的时候把\n算在%c里面,一定要加一个空格
if(setchoose=='y'){
set=1;
printf("修改成功\n");
} else{
set=0;
}
}
//2.保留小数
else if(userput=='2')
{
printf("你希望保留几位小数?:");
scanf("%d",&point);//这里不需要经过执行区,因为有默认保留几位小数,要必须经过这里才能修改,放在执行区的话就会每次都修改
}
}
//按下不存在按键
else{
printf("请按下正确的按键,回车键继续");
while(getchar()!='\n');
}
//设置选项卡执行区
if(set==1)//选择的是弄yes
{
printf("***************以上是历史内容****************\n");
}
else//选择的是no ,或者不选
{
//为了让布局美观,每次算完之后清空屏幕 ,用到了头文件#include<windows.h>
system("cls") ;
}
}while(1);
return 0;
}
第七版
版本特性:
专业计算功能已经超出作者能力范畴!!!!结束了罪恶的一生。
实验小结
收获最大的地方还是在设计一个计算器上面:
1.目前还没有学到循环结构,只学了分支结构,这就需要额外学习循环结构
2.计算器里面可以有很多功能,比如说你想实现保留几位小数,要如何实现?每一次执行完程序如何让程序更加美观?这就需要查阅资料,百度是一个神奇的网站
3.设计一个计算器还涉及到很多细节,比如如何保证用户输入正确格式?如何判断错误格式,又要如何重新输入?又比如一个%f
和%lf
的区别可能导致程序运算错误……
另外一个收货就是记笔记
1.当你上课记笔记的时候,很难兼顾笔记工整和听课效率,所以要舍弃笔记工整,尝试用草稿纸先记笔记,后面再整理思路,事半功倍!
2.当有一本纸质教材的时候,记笔记也会很轻松,可以先把上课内容注释在书本上,之后复习翻阅书籍也是一个不错的选择。