为什么这个c代码的结果是;天数:33“;而不是",;天数:30“;?
我正在准备一个测试,在一个旧的测试中,有人问我下面代码的输出是什么。我对这段代码如何输出“days:33”感到困惑。有什么办法可以很容易地解释吗 编辑:谢谢你的解释,是的,我知道这段代码的逻辑毫无意义(就计算给定年份中给定月份的实际天数而言),这只是一道老试题为什么这个c代码的结果是;天数:33“;而不是",;天数:30“;?,c,switch-statement,label,break,C,Switch Statement,Label,Break,我正在准备一个测试,在一个旧的测试中,有人问我下面代码的输出是什么。我对这段代码如何输出“days:33”感到困惑。有什么办法可以很容易地解释吗 编辑:谢谢你的解释,是的,我知道这段代码的逻辑毫无意义(就计算给定年份中给定月份的实际天数而言),这只是一道老试题 #include <stdio.h> int calcDays(int, int); int main(){ int days; days = calcDays(11, 2020);
#include <stdio.h>
int calcDays(int, int);
int main(){
int days;
days = calcDays(11, 2020);
printf("days: %d\n", days);
return 0;
}
int calcDays(int month, int yr){
int days = 28;
switch(month)
{
case 2: days += 1 - yr % 4;
case 4:
case 6:
case 9:
case 11: days += 2;
default: days += 3;
}
return(days);
}
#包括
整数计算日(整数,整数);
int main(){
国际日;
天数=计算天数(112020);
printf(“天数:%d\n”,天数);
返回0;
}
整数计算日(整数月,整数年){
整日=28天;
开关(月)
{
案例2:天数+=1年%4;
案例4:
案例6:
案例9:
案例11:天数+=2天;
默认值:天数+=3天;
}
返回(天);
}
您的交换机最后没有中断,因此所有内容都将添加到天中。试试这个:
switch(month)
{
case 2: days += 1 - yr % 4; break;
case 4:
case 6:
case 9:
case 11: days += 2; break;
default: days += 3; break;
}
您需要防止您的
案例
失败:
int计算日(int月,int年){
整日=28天;
开关(月)
{
案例2:
天数+=年;
打破
案例4:
案例6:
案例9:
案例11:
天数+=2天;
打破
违约:
天数+=3天;
}
返回(天);
}
一种更简单、更难出错的方法:
int计算日(int月,int年){
开关(月)
{
案例2:
返回28+偏移量(年);
打破
案例4:
案例6:
案例9:
案例11:
返回30;
打破
违约:
返回31;
}
返回(天);
}
这两项都需要有效的leapOffset()
计算:
int-leappoffset(int-yr){
回报率((年率%4==0)和&(年率%100!=0)| |(年率%400==0))?1:0;
}
在函数的switch语句中,这两个标签之间没有break语句
case 11: days += 2;
default: days += 3;
所以这些声明
days += 2;
days += 3;
days += 1 - yr % 4;
days += 2;
days += 3
依次进行评估
如果有一个break语句,比如
case 11: days += 2; break;
default: days += 3;
例如,如果参数month设置为2,则所有这些语句
days += 2;
days += 3;
days += 1 - yr % 4;
days += 2;
days += 3
在这个代码片段中
case 2: days += 1 - yr % 4;
case 4:
case 6:
case 9:
case 11: days += 2;
default: days += 3
将进行评估
注意这句话
days += 1 - yr % 4;
没有意义,因为除以4的余数可以是0、1、2或3。您得到的是33而不是30,因为在case:11中没有中断。您可能希望将其写为:
case 11: {
days += 2;
break;
}
switch
语句是一个“计算跳转”。它所做的只是跳转到附加语句中的一个标签(通常是包含多个带标签语句的复合语句),或者,如果没有标签匹配,跳转到附加语句之外
因此,switch(month)
跳转到标记为case2
的语句或标记为case4
的语句,或标记为case6
的语句,或标记为case9
的语句,或标记为case11
的语句或标记为default
的语句。然后程序继续正常执行:它执行跳转到的语句,以及跳转到之后的语句,以及跳转到之后的语句,依此类推
标签不会将语句划分为单独的集合。案例2不在案例4
标签所在的位置结束。执行case2
语句后,继续控制case4
语句;它不会跳出开关
语句
因此,一旦程序跳转到语句case11:days+=2代码>,执行天+=2代码>。然后进入下一个语句,它是default:days+=3代码>,并执行该命令
请注意,默认值:天+=3
是一个语句,案例11:days+=2也是一个语句代码>。将标签放在任何语句前面会生成一个新语句:
days+=2代码>是一条语句<代码>案例11:天数+=2
是一条语句(包含另一条语句,days+=2;
)<代码>案例9:案例11:天数+=2
是一条语句(包含另外两条语句)<代码>案例6:案例9:案例11:天数+=2
是一个语句,依此类推。注意yr%4
是一个介于0到3之间的数字。您的开关/案例
没有中断
s。提示:案例
失败。始终中断!看起来您需要阅读有关“中断”的声明您还需要阅读公历闰年的完整规则。