user-0 提问: 关于加减乘除的C程序求助

回复:
user: user-1
content: 仅供参考：//运用C语言开发一个“小学生算术四则运算测试系统”。该系统是让计算机充当一位给小学生布置作业的算术老师，为学生出题并阅卷。该系统要求实现下列功能： //①为小学生出题（分别进行+、-、*、/等不同运算）。 //②学生做题后，进行评阅。学生每做一题后，评阅给出“答题正确，很好”或“答题错误，重做”等信息。 //③加、减、乘、除运算功能可以自由选择实现。 //④运算数值可控制在两位数的四则运算范围内。 #include <stdio.h> #include <stdlib.h> #include <time.h> int c,a,b,r,ri; void main() {     srand( (unsigned)time( NULL ) );     system("cls");     printf("小学生算术四则运算测试系统\n");     while (1) {         printf("1加法 2减法 3乘法 4除法 0退出:");fflush(stdout);         rewind(stdin);         scanf("%d",&c);         if (0==c) break;         switch (c) {         case 1:             a=rand()%100;             b=rand()%100;             r=a+b;             while (1) {                 printf("%d+%d=?",a,b);fflush(stdout);                 rewind(stdin);                 scanf("%d",&ri);                 if (ri==r) {                     printf("答题正确，很好！\n");                     break;                 } else {                     printf("答题错误，请重做。\n");                 }             }         break;         case 2:             a=1+rand()%99;             b=rand()%a;             r=a-b;             while (1) {                 printf("%d-%d=?",a,b);fflush(stdout);                 rewind(stdin);                 scanf("%d",&ri);                 if (ri==r) {                     printf("答题正确，很好！\n");                     break;                 } else {                     printf("答题错误，请重做。\n");                 }             }         break;         case 3:             a=rand()%99;             b=rand()%99;             r=a*b;             while (1) {                 printf("%d*%d=?",a,b);fflush(stdout);                 rewind(stdin);                 scanf("%d",&ri);                 if (ri==r) {                     printf("答题正确，很好！\n");                     break;                 } else {                     printf("答题错误，请重做。\n");                 }             }         break;         case 4:             a=2+rand()%998;             b=1+rand()%(a/2);             while (1) {                 if (0==a%b) break;                 b--;             }             r=a/b;             while (1) {                 printf("%d/%d=?",a,b);fflush(stdout);                 rewind(stdin);                 scanf("%d",&ri);                 if (ri==r) {                     printf("答题正确，很好！\n");                     break;                 } else {                     printf("答题错误，请重做。\n");                 }             }         break;         }     } }

user: user-2
content: 引用 9 楼 拥抱Linux 的回复:[quote=引用 8 楼 Avril_SHE 的回复:] [quote=引用 5 楼 2019别做废物 的回复:] 楼上正解 补充一下 你看看你函数里定义的ch变量 应该是char型不是int 剩下的应该就是逻辑运算的问题了 你可以把你的每个条件想成1和0问题就会很简单的解决了  getchar的返回值可以赋给int类型变量，C primer plus里有这么写的，因为字符本质上以整数存储的，不知道说的对不对？但从编程习惯说，getchar还是应该只处理char类型变量，不应该处理其他类型变量。[/quote]  嗯，函数getchar()定义在C标准库的头文件<stdio.h>当中，原型是「int getchar(void);」，可以看到它的返回值本来就是 int 型，所以你的用法是对的。 而且有些时候，比如检测输入字符是否合理的循环条件时，必须用 int 变量来接收 getchar() 的返回值， 如果用 char 的话还可能导致死循环。 还有就是getchar() 的值后面需要用于与其它字符比较的时候，也最好用 int 型来接收。 顺便提一下，单个的 字符 常量 实际上 是 int 型 ，而不是 char  型。试试下面的结果：  #include <stdio.h>  int main(int argc, char const *argv[]) { 	char a = 'a'; 	printf("sizeof var a = %zu\n", sizeof(a)); 	printf("sizeof character 'a' = %zu\n", sizeof('a')); 	return 0; } [/quote]  学到了~

user: user-3
content: 这种问题根本不需要来论坛问，你只要改成这样自己就能找到问题 printf("Please respond with a,s,m,d or q.\n"); -> printf("Please respond with a,s,m,d or q, your input %c is wrong!\n", ch);

user: user-4
content: 引用 8 楼 Avril_SHE 的回复:[quote=引用 5 楼 2019别做废物 的回复:] 楼上正解 补充一下 你看看你函数里定义的ch变量 应该是char型不是int 剩下的应该就是逻辑运算的问题了 你可以把你的每个条件想成1和0问题就会很简单的解决了  getchar的返回值可以赋给int类型变量，C primer plus里有这么写的，因为字符本质上以整数存储的，不知道说的对不对？但从编程习惯说，getchar还是应该只处理char类型变量，不应该处理其他类型变量。[/quote]  嗯，函数getchar()定义在C标准库的头文件<stdio.h>当中，原型是「int getchar(void);」，可以看到它的返回值本来就是 int 型，所以你的用法是对的。 而且有些时候，比如检测输入字符是否合理的循环条件时，必须用 int 变量来接收 getchar() 的返回值， 如果用 char 的话还可能导致死循环。 还有就是getchar() 的值后面需要用于与其它字符比较的时候，也最好用 int 型来接收。 顺便提一下，单个的 字符 常量 实际上 是 int 型 ，而不是 char  型。试试下面的结果：  #include <stdio.h>  int main(int argc, char const *argv[]) { 	char a = 'a'; 	printf("sizeof var a = %zu\n", sizeof(a)); 	printf("sizeof character 'a' = %zu\n", sizeof('a')); 	return 0; }

user: user-0
content: 引用 5 楼 2019别做废物 的回复:楼上正解 补充一下 你看看你函数里定义的ch变量 应该是char型不是int 剩下的应该就是逻辑运算的问题了 你可以把你的每个条件想成1和0问题就会很简单的解决了  getchar的返回值可以赋给int类型变量，C primer plus里有这么写的，因为字符本质上以整数存储的，不知道说的对不对？但从编程习惯说，getchar还是应该只处理char类型变量，不应该处理其他类型变量。

user: user-4
content: 引用 6 楼 Avril_SHE 的回复:感觉你的帮助，非常有用！ 对于您的中肯的评价，俺同样觉得非常有用！ 如有帮助，烦请及时结帖，给分吧！ ：-） ～

user: user-0
content: 引用 4 楼 拥抱Linux 的回复:（1）选择菜单的while循环的判断语句不对，用逻辑或的话，意思是只要有一个为真，整个逻辑或的值就是真，也就是说 逻辑或运算符 左边的值为假的话， 逻辑或右边的表达式会继续检查。例如 ch 的值是 字符 'a' 的话，第一个 比较表达式的结果 ch != 'a' 是假，但是第二个比较表达式 ch != 's' 的结果就是真了呀，而后面的  逻辑与  右边的 ch != 'q' 在这种情况下也是真 ，那么整个判断条件的结果就是真， 那么就会进入循环体内部。应该改成全部都用 逻辑与， 意思是 只要不是这几个字符当中的其中一个 就是真，才进入循环内，而如果 ch 是这几个字符当中的任意一个，那么就进入下一阶段了。  while (ch != 'a' && ch != 's' && ch && 'm' && ch != 'd' && ch != 'q')  （2）get_num 函数 和 get_first 函数，没有清空输入缓冲区的处理，后续仍然会有不符合期待的运行结果。 虽然 get_first 函数中对输入缓冲区的第一个 '\n' 字符进行了吸收处理，但是 get_num 函数在后面会连续运行两次，所以 还有一个 '\n'  会被下一轮的 ch 接收到。因此，需要对输入缓冲区进行完全的清理。 （3）switch-case结构中的 printf 语句，格式符 与 后面的变量 的对应数量不相符， 输出结果与期望结果不同。应该把需要输出的变量在后面补充完整。比如正常范围的除法的输出语句： printf("%.2f / %.2f = %.2f.\n", num_1, num_2, num_1 / num_2); ～   感觉你的帮助，非常有用！

user: user-2
content: 楼上正解 补充一下 你看看你函数里定义的ch变量 应该是char型不是int 剩下的应该就是逻辑运算的问题了 你可以把你的每个条件想成1和0问题就会很简单的解决了

user: user-4
content: （1）选择菜单的while循环的判断语句不对，用逻辑或的话，意思是只要有一个为真，整个逻辑或的值就是真，也就是说 逻辑或运算符 左边的值为假的话， 逻辑或右边的表达式会继续检查。例如 ch 的值是 字符 'a' 的话，第一个 比较表达式的结果 ch != 'a' 是假，但是第二个比较表达式 ch != 's' 的结果就是真了呀，而后面的  逻辑与  右边的 ch != 'q' 在这种情况下也是真 ，那么整个判断条件的结果就是真， 那么就会进入循环体内部。应该改成全部都用 逻辑与， 意思是 只要不是这几个字符当中的其中一个 就是真，才进入循环内，而如果 ch 是这几个字符当中的任意一个，那么就进入下一阶段了。  while (ch != 'a' && ch != 's' && ch && 'm' && ch != 'd' && ch != 'q')  （2）get_num 函数 和 get_first 函数，没有清空输入缓冲区的处理，后续仍然会有不符合期待的运行结果。 虽然 get_first 函数中对输入缓冲区的第一个 '\n' 字符进行了吸收处理，但是 get_num 函数在后面会连续运行两次，所以 还有一个 '\n'  会被下一轮的 ch 接收到。因此，需要对输入缓冲区进行完全的清理。 （3）switch-case结构中的 printf 语句，格式符 与 后面的变量 的对应数量不相符， 输出结果与期望结果不同。应该把需要输出的变量在后面补充完整。比如正常范围的除法的输出语句： printf("%.2f / %.2f = %.2f.\n", num_1, num_2, num_1 / num_2); ～