简易C语言计算器:从基础到优化的完整指南 目录一、项目目标二、编写代码1.代码设计2.运算逻辑3.菜单页面4.main函数三、代码优化与改进1.main函数精简1清除重复部分2删去switch语句2.优化使用体验1计算完成后清除页面内容2交互后输入任意键继续四、完整代码展示1.优化前代码2.优化后代码一、项目目标运用c语言根据用户输入来实现整数之间计算的功能包括加、减、乘、除、模运算。结果只保留整数部分二、编写代码1.代码设计初步判断代码大概分为三部分main函数、菜单页面、运算逻辑。我们先会设计出一个可以正常运行的版本然后再进行改进。2.运算逻辑我们先完成计算器最重要的功能------运算逻辑。首先我们需要将不同种类的运算分装成不同的函数函数返回类型均为int。传入两个值x和y后进行相应的运算返回运算的结果。其中我们必须要注意的是除法运算和取模运算的除数不能为0我们需要在运算前进行判断保证程序安全性。代码如下所示int add(int x, int y) //加法 { return x y; } int subtract(int x,int y) //减法 { return x - y; } int multiply(int x, int y) //乘法 { return x * y; } int divide(int x, int y) //除法 { if (y 0) { printf(除数不能为 0请重新输入\n); return 0; } return x / y; } int mod(int x, int y) //取模 { if (y 0) { printf(除数不能为 0请重新输入\n); return 0; } return x % y; }3.菜单页面为了使代码整洁我们将菜单页面单独设计一个部分。依靠打印功能我们可以简单设计一个菜单页面提示用户输入不同的数字来触发不同的计算。代码如下所示void menu() { printf( 计 算 器 \n); printf(\n); printf(\n); printf( 1.加法 2.减法 3.乘法 \n); printf( 4.除法 5.取模 \n); printf( 0.exit \n); printf(\n); printf(\n); printf(请选择计算方式 ); }4.main函数在main函数中我们需要接受用户输入值来完成计算工作。我们可以先写一个简单的框架运用switch语句来根据不同的输入值进入到不同的函数中。当然为了安全我们也需要对输入值进行判断。代码如下所示int main() { int start 0; int a 0; int b 0; int result0; while(1) { menu(); int safe scanf(%d, start); //如果成功获取对应类型的值scanf函数会根据返回值的个 数返回值后文中的scanf判断输入是同一逻辑 if (safe ! 1) { printf(输入非法请重试\n); while (getchar() ! \n); //清除缓存防止程序死循环 continue; } if (start 0) { printf(感谢你的使用再见\n); break; } switch (start) { case 1: //加法 { printf(请输入两个运算值用空格隔开:); int safescanf(%d %d,a,b); if (safe ! 2) { printf(输入非法请重试\n); continue; } resultadd(a,b); printf(%d,result); break; } case 2: //减法 { printf(请输入两个运算值用空格隔开:); int safescanf(%d %d,a,b); if (safe ! 2) { printf(输入非法请重试\n); continue; } result subtract(a,b); printf(%d,result); break; } case 3: //乘法 { printf(请输入两个运算值用空格隔开:); int safescanf(%d %d,a,b); if (safe ! 2) { printf(输入非法请重试\n); continue; } result multiply(a,b); printf(%d,result); break; } case 4: //除法 { printf(请输入两个运算值用空格隔开:); int safescanf(%d %d,a,b); if (safe ! 2) { printf(输入非法请重试\n); continue; } result divide(a,b); printf(%d,result); break; } case 5: //取模 { printf(请输入两个运算值用空格隔开:); int safescanf(%d %d,a,b); if (safe ! 2) { printf(输入非法请重试\n); continue; } result mod(a,b); printf(%d,result); break; } default: //其他数字输入 { printf(输入错误请输入0-5之间的值\n); break; } } } }这样这三个主要的函数的雏形我们就都写完了。接下来让我们对这些代码进行优化。三、代码优化与改进1.main函数精简1清除重复部分在我们完成main函数的过程中我们可以注意到类似于下面代码的形式在switch语句里面反复出现。不仅极大的增加了我们代码的重复率而且我们写的时候也很复杂。printf(请输入两个运算值用空格隔开:); int safescanf(%d %d,a,b); if (safe ! 2) { printf(输入非法请重试\n); continue; } resultadd(a,b); break;所以我们可以写一个函数cal来帮我们把这一大堆的代码精简成一个模块。对这个函数进行思考可以发现这个cal函数没有任何的返回值只需要传入我们需要的运算就可以进行处理。那么如何将一个函数传入另一个函数中呢也就是回调函数这就需要我们将运算逻辑函数的地址传入cal这个函数。具体代码如下:void cal(int(*p)(int, int)) { int a 0; int b 0; printf(请输入两个运算值用空格隔开:); int safescanf(%d %d,a,b); if (safe ! 2) { printf(输入非法请重试\n); return; } printf(%d\n,p(a, b)); }再将我们switch语句中的一大串都替换成对cal函数的引用将main函数变为下面的形式。int main() { int start 0; while(1) { menu(); int safe scanf(%d, start); if (safe ! 1) { while (getchar() ! \n); //清除缓存防止程序死循环 printf(输入非法请重试\n); continue; } switch (start) { case 1: cal(add); break; case 2: cal(subtract); break; case 3: cal(multiply); break; case 4: cal(divide); break; case 5: cal(mod); break; default: printf(输入错误请输入0-5之间的值\n); break; } } }这样一看代码就变得更加简洁明了了。2删去switch语句在上文中我们虽然简化了switch语句。但整体来看switch语句还是比较大的不利于阅读。所以我们可以运用指针数组。我们不妨将不同运算逻辑函数的指针都作为一个数组中的一个元素利用数组的下标来判断用户需要什么运算。因此main函数可以进一步被缩减为int main() { int start 0; int (*select[6])(int, int) { NULL,add,subtract,multiply,divide,mod }; //因为用户的输入除了退出程序之外都是1-5的值 所以将第一个元素改为NULL起到一个占位的作用 while(1) { menu(); int safe scanf(%d, start); if (safe ! 1) { while (getchar() ! \n); //清除缓存防止程序死循环 printf(输入非法请重试\n); continue; } if (start 0) { printf(感谢你的使用再见\n); break; } else if (start 0 start 6) { cal(select[start]); } else { printf(输入非法请重试\n); continue; } } }2.优化使用体验1计算完成后清除页面内容在每一次我们完成运算后如果我们进行下一次运算上一次运算的菜单、内容依旧在屏幕上显示不够美观。所以我们可以在每一次运行结束时进行一次清屏操作需要stdlib.h头文件执行清屏的操作可以可以放在菜单栏中。代码如下所示void menu() { system(cls); //清屏 printf( 计 算 器 \n); printf(\n); printf(\n); printf( 1.加法 2.减法 3.乘法 \n); printf( 4.除法 5.取模 \n); printf( 0.exit \n); printf(\n); printf(\n); printf(请选择计算方式 ); }2交互后输入任意键继续在完成清屏操作的时候我们注意到一个问题。当我们完成了一次运算时因为在main函数中的循环导致一旦计算完成程序就会回到开头重新执行mune函数使程序立刻清屏。为了解决这一问题我们可以让用户摁下任意键后再执行下一次循环。这不仅可以解决上面清屏过快的问题还可以让用户自由选择下一次运算的时机。需要stdlib.h头文件且只能在windows环境下运行让我们在cal函数的结尾加上system(pause);就可以实现这一功能程序会自动提醒用户摁下任意键后继续。void cal(int(*p)(int, int)) { int a 0; int b 0; printf(请输入两个运算值用空格隔开:); int safescanf(%d %d,a,b); if (safe ! 2) { printf(输入非法请重试\n); return; } printf(%d\n,p(a, b)); system(pause); while (getchar() ! \n); // 清掉残留 }3提前判断运算数值是否合法在上文我们设置了在除数为0时报错的功能但是这同时也会返回一个错误值。不仅如此在这种情况下我们也将计算的功能与判断的功能写在了一起没有让不同功能彼此独立。所以我们应该在将值导入到除法运算和取模运算前进行判断数据是否合法。修改后代码如下void cal(int(*p)(int, int),int start) { int a 0; int b 0; printf(请输入两个运算值用空格隔开:); int safescanf(%d %d,a,b); if (safe ! 2 || (b 0 (start4||start5))) { printf(输入非法请重试\n); return; } printf(%d\n,p(a, b)); system(pause); }四、完整代码展示1.优化前代码#define _CRT_SECURE_NO_WARNINGS //这行代码用于解决在vs studio中安全报错的问题 #include stdio.h int add(int x, int y) //加法 { return x y; } int subtract(int x,int y) //减法 { return x - y; } int multiply(int x, int y) //乘法 { return x * y; } int divide(int x, int y) //除法 { if (y 0) { printf(除数不能为 0 请重新输入\n); return 0; } return x / y; } int mod(int x, int y) //取模 { if (y 0) { printf(除数不能为 0 ,请重新输入\n); return 0; } return x % y; } void menu() { printf( 计 算 器 \n); printf(\n); printf(\n); printf( 1.加法 2.减法 3.乘法 \n); printf( 4.除法 5.取模 \n); printf( 0.exit \n); printf(\n); printf(\n); printf(请选择计算方式 ); } int main() { int start 0; int a 0; int b 0; int result0; while(1) { menu(); int safe scanf(%d, start); if (safe ! 1) { while (getchar() ! \n); //清除缓存防止程序死循环 printf(输入非法请重试\n); continue; } if (start 0) { printf(感谢你的使用再见\n); break; } switch (start) { case 1: { printf(请输入两个运算值用空格隔开:); int safescanf(%d %d,a,b); if (safe ! 2) { printf(输入非法请重试\n); continue; } resultadd(a,b); printf(%d, result); break; } case 2: { printf(请输入两个运算值用空格隔开:); int safescanf(%d %d,a,b); if (safe ! 2) { printf(输入非法请重试\n); continue; } result subtract(a,b); printf(%d,result); break; } case 3: { printf(请输入两个运算值用空格隔开:); int safescanf(%d %d,a,b); if (safe ! 2) { printf(输入非法请重试\n); continue; } result multiply(a,b); printf(%d,result); break; } case 4: { printf(请输入两个运算值用空格隔开:); int safescanf(%d %d,a,b); if (safe ! 2) { printf(输入非法请重试\n); continue; } result divide(a,b); printf(%d,result); break; } case 5: { printf(请输入两个运算值用空格隔开:); int safescanf(%d %d,a,b); if (safe ! 2) { printf(输入非法请重试\n); continue; } result mod(a,b); printf(%d,result); break; } default: { printf(输入错误请输入0-5之间的值\n); break; } } } }2.优化后代码#define _CRT_SECURE_NO_WARNINGS //这行代码用于解决在vs studio中安全报错的问题 #include stdio.h #include stdlib.h int add(int x, int y) //加法 { return x y; } int subtract(int x,int y) //减法 { return x - y; } int multiply(int x, int y) //乘法 { return x * y; } int divide(int x, int y) //除法 { return x / y; } int mod(int x, int y) //取模 { return x % y; } void menu() { system(cls); printf( 计 算 器 \n); printf(\n); printf(\n); printf( 1.加法 2.减法 3.乘法 \n); printf( 4.除法 5.取模 \n); printf( 0.exit \n); printf(\n); printf(\n); printf(请选择计算方式 ); } void cal(int(*p)(int, int),int start) { int a 0; int b 0; printf(请输入两个运算值用空格隔开:); int safescanf(%d %d,a,b); if (safe ! 2 || (b 0 (start4||start5))) { printf(输入非法请重试\n); system(pause); return; } printf(%d\n,p(a, b)); system(pause); } int main() { int start 0; int (*select[6])(int, int) { NULL,add,subtract,multiply,divide,mod }; while(1) { menu(); int safe scanf(%d, start); if (safe ! 1) { printf(输入非法请重试\n); while (getchar() ! \n); system(pause); continue; } if (start 0) { printf(感谢你的使用再见\n); break; } else if (start 0 start 6) { cal(select[start],start); while (getchar() ! \n); continue; } else { printf(输入非法请重试\n); system(pause); continue; } } }五、结语以上就是本期内容。限于个人能力文章难免有考虑不周或表述不清的地方欢迎大家在评论区批评指正一起交流进步