题目
三个整数降序输出(程序改错)
描述
#include <stdio.h>
int main () {
int a,b,c;
scanf("%d %d %d",&a,&b,&c);
if(a<b){
if(b<c)
printf("%d %d %d\n",c,b,a);
else
printf("%d %d %d\n",b,c,a);
}
else if(b<c){
if(c<a)
printf("%d %d %d\n",a,c,b);
else
printf("%d %d %d\n",c,a,b);
}
else if(c<a){
if(a<b)
printf("%d %d %d\n",b,a,c);
else
printf("%d %d %d\n",a,b,c);
}
return 0;
}
输入
三个空格分隔的互不相同的整数(-100<=值<=100)
输出
降序输出这3个整数,之间也用空格分隔。
输入样例 1
1 2 3
输出样例 1
3 2 1
来源
福州大学·软件学院·软件工程系·王灿辉
操作
直接用测试数据去试
发现对测试数据是可以的。
检查程序的逻辑
光在代码里面一边加注释一边看,发现我的逻辑和程序的作者一样混乱。于是我就在稿纸上把a、b、c所有可能的大小关系按顺序一一列举。先列出不等的关系,比如a < b < c,共六种;然后再在每个不等关系后面考虑部分相等的关系,比如a == b < c,a < b == c,这样虽然会有重复,但是没关系;最后再考虑a == b == c。接着我逐一排除了能判断的情况,就确定了程序的问题。
注意:这只是草稿,if语句的逻辑表达式千万不能这么写!
加了注解的代码如下:
#pragma warning(disable:4996)
#include <stdio.h>
int main() {
int a, b, c;
scanf("%d %d %d", &a, &b, &c);
if (a < b) {//一
if (b < c)// a < b < c
printf("%d %d %d\n", c, b, a);//正确
else/* a < b >= c,这里假定了 c > a,因此无法判断 c < a < b 的情况
另外三种情况:b > c > a、b > c == a、b == c > a 能正确判断 */
printf("%d %d %d\n", b, c, a);//2,3,1 -> 3,1,2 要判断a和c的关系!
}
else if (b < c) {//二 a >= b < c
if (c < a)//如果 a == b,就是 a == b > c,矛盾,故执行else;所以这只能是 b < c < a
printf("%d %d %d\n", a, c, b);//正确
else//c > a > b 或 c == a > b 或 c > a == b
printf("%d %d %d\n", c, a, b);//正确
}
else if (c < a) {//一和二都不成立,就意味着 a >= b >= c
if (a < b)//这个肯定不会执行
printf("%d %d %d\n", b, a, c);
else// a >= b,在这里肯定成立
printf("%d %d %d\n", a, b, c);
}
return 0;
}
修改
在 a < b >= c 那里讨论好a与c的大小关系;删除肯定不执行的代码。
修改后的代码如下:
#pragma warning(disable:4996)
#include <stdio.h>
int main() {
int a, b, c;
scanf("%d %d %d", &a, &b, &c);
if (a < b) {//一
if (b < c)// a < b < c
printf("%d %d %d\n", c, b, a);//正确
else if (c >= a)// b > c > a 或 b == c > a 或 b > c == a
printf("%d %d %d\n", b, c, a);
else// b > a > c
printf("%d %d %d\n", b, a, c);
}
else if (b < c) {//二 a >= b < c
if (c < a)//如果 a == b,就是 a == b > c,矛盾,故执行else;所以这只能是 b < c < a
printf("%d %d %d\n", a, c, b);//正确
else//c > a > b 或 c == a > b 或 c > a == b
printf("%d %d %d\n", c, a, b);//正确
}
else if (c < a) {//一和二都不成立,就意味着 a >= b >= c
printf("%d %d %d\n", a, b, c);
}
return 0;
}
提交到在线评测系统上,答案正确!
自己重写
那我就不会用一长串的if了。我要直接调用排序函数!
#pragma warning(disable:4996)
#include <stdio.h>
#include <stdlib.h>
int cmp(const void* arg1, const void* arg2);
int main()
{
int n[3];
scanf("%d%d%d", &n[0], &n[1], &n[2]);
qsort(n, 3, sizeof(int), cmp);
printf("%d %d %d", n[0], n[1], n[2]);
return 0;
}
int cmp(const void* arg1, const void* arg2)
{
return *(int*)arg2 - *(int*)arg1;
}
同样正确!
写简单一些的代码,尽量多地使用库函数,何乐而不为呢?
总结
在一道题上折腾了这么长时间,肯定会有人问,值得吗?是值得的。作业不应该被草草应付。我们应该领悟到作业中要求的思想方法,比如本题中的改错,应该让手、脑、电脑和纸、笔一起动起来,才能更快地发现问题,更高效地解决问题。
结语
写代码的时候不要忘了祝我们伟大的祖国母亲生日快乐哟!我爱你,中国!