声明:这些内容主要是面向C语言的初学者,尤其是正在学习C语言的学生。
程序优化是个很大的话题,一些经典编程书籍上对此已做过探讨。在这里,我主要是针对学生作业中的一些问题进行讨论,尽量想办法减少程序中的冗余、使程序变得更简练,可以说是比较初级的程序优化。更高级的优化主要是针对编译器进行的,如何写代码使编译出来的程序执行效率更高,以后抽空再讨论。
例: 第五章课后第10题:编程从键盘输入某年某月,输出该年的该月拥有的天数(要求用switch语句实现)。
分析:
每年的1,3,5,7,8,10,12月都是31天,4,6,9,11月都是30天,只有2月是个特例,闰年的2月是29天,平年的2月是28天。所以程序中需要判断输入的年份是否闰年,对2月要特殊处理。
某位学生的程序:
#include "stdio.h"
int main()
{
int year,month;
printf("Please input year:");
scanf("%d",&year);
printf("Please input month:");
scanf("%d",&month);
if((year%4==0 && year%100!=0) || year%400==0) //闰年
{
switch(month)
{
case 1: printf("%d年%d月有31天",year,month); break;
case 2: printf("%d年%d月有29天",year,month); break;
case 3: printf("%d年%d月有31天",year,month); break;
case 4: printf("%d年%d月有30天",year,month); break;
case 5: printf("%d年%d月有31天",year,month); break;
case 6: printf("%d年%d月有30天",year,month); break;
case 7: printf("%d年%d月有31天",year,month); break;
case 8: printf("%d年%d月有31天",year,month); break;
case 9: printf("%d年%d月有30天",year,month); break;
case 10: printf("%d年%d月有31天",year,month); break;
case 11: printf("%d年%d月有30天",year,month); break;
case 12: printf("%d年%d月有31天",year,month); break;
}
}
else
{
switch(month)
{
case 1: printf("%d年%d月有31天",year,month); break;
case 2: printf("%d年%d月有28天",year,month); break;
case 3: printf("%d年%d月有31天",year,month); break;
case 4: printf("%d年%d月有30天",year,month); break;
case 5: printf("%d年%d月有31天",year,month); break;
case 6: printf("%d年%d月有30天",year,month); break;
case 7: printf("%d年%d月有31天",year,month); break;
case 8: printf("%d年%d月有31天",year,month); break;
case 9: printf("%d年%d月有30天",year,month); break;
case 10: printf("%d年%d月有31天",year,month); break;
case 11: printf("%d年%d月有30天",year,month); break;
case 12: printf("%d年%d月有31天",year,month); break;
}
}
}
在上面的程序中,用了两个非常相似的switch语句,除了2月,其他部分都是完全一样的。在一个程序中,如果同样的代码片段重复出现,我们就需要考虑对其进行优化(重构),减少冗余的部分。对闰年的判断实际上只是对2月有用,所以没有必要把其他月份的输出也放在if else语句中去,因此可以把if else语句放到case 2的后面,这样就可以去掉一个switch语句。另外,在switch语句中,case语句的顺序可以是任意的,不一定要按顺序从1到12排列,因此我们可以把31天和30天的月份分别放到一起,共享输出语句。改进后的代码如下:
#include "stdio.h"
int main()
{
int year,month,flag=0;
printf("Please input year:");
scanf("%d",&year);
printf("Please input month:");
scanf("%d",&month);
if((year%4==0 && year%100!=0) || year%400==0)
flag = 1; //如果是闰年,则置flag为1
switch(month)
{
case 2: if(flag)
printf("%d年2月有29天",year);
else
printf("%d年2月有28天",year);
break;
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12: printf("%d年%d月有31天",year,month); break;
case 4:
case 6:
case 9:
case 11: printf("%d年%d月有30天",year,month); break;
}
}
改进后的程序比原来的程序简练了许多。当然,还有很多别的写法,大家可以自己去尝试。