使用带有日期和季节的Switch语句

n9vozmp4  于 2022-12-11  发布在  其他
关注(0)|答案(3)|浏览(133)

我试图只使用if语句和switch语句创建一个日期标识符,我试着先让两个组件独立工作,然后让它们一起工作,但我还是不能让我的switch语句工作。我希望我的switch语句通过检查日期和月份来显示季节,以查看我们处于哪个季节,但我不知道如何做到这一点。下面是我的代码:

/* Switch statement to determine season for day and month */
// Using it with a "m" on it's own works, how do I get it working for specific days?
switch (m)
    {
    case 12:
    case 1:
    case 2:
        if ((m == 12 && d >=21) || (m == 1) || (m == 2) || (m == 3 && m < 21))  
            printf("The season is Winter.\n");
        break;
    case 3:
    case 4:
    case 5:
        if ((m == 3 && d >= 21) || (m == 4) || (m == 5) || (m == 6 && d < 21))
            printf("The season is Spring.\n");
        break;
    case 6:
    case 7:
    case 8:
        if ((m == 6 && d >= 21) || (m == 7) || (m == 8) | (m == 9 && d < 21))
            printf("The season is Summer.\n");
        break;
    case 9:
    case 10:
    case 11:
        if ((m == 9 && d >= 21) || (m == 10) || (m == 11) || (m == 12 && d < 21))
            printf("The season is Autumn.\n");
    default:
        break;
    }
}

我试着让每个部分的代码独立工作,但是我仍然不确定我的switch语句。我怎样才能让它工作几天甚至几个月?有没有办法仍然用switch语句做到这一点?
输出示例:

20/06/2022 = Spring
21/06/2022 = Summer
gmol1639

gmol16391#

对于3月1日(以及其他日期),示例将失败,因为Winter case中没有列出3的case。您根本不需要switch语句:

if ((m == 12 && d >=21) || (m == 1) || (m == 2) || (m == 3 && d < 21))  
    printf("The season is Winter.\n");
else if ((m == 3 && d >= 21) || (m == 4) || (m == 5) || (m == 6 && d < 21))
    printf("The season is Spring.\n");
else if ((m == 6 && d >= 21) || (m == 7) || (m == 8) | (m == 9 && d < 21))
    printf("The season is Summer.\n");
else
    printf("The season is Autumn.\n");
suzh9iv8

suzh9iv82#

如果你必须使用switch,那么你必须把边界月份(March,June,September,December)放到自己的例中:

const char *season = NULL;
switch (m)
{
case 1:
case 2:
    season = "Winter";
    break;
case 3:
    season = (d < 21) ? "Winter" : "Spring";
    break;
case 4:
case 5:
    season = "Spring";
    break;
case 6:
    season = (d < 21) ? "Spring" : "Summer";
    break;
case 7:
case 8:
    season = "Summer";
    break;
case 9:
    season = (d < 21) ? "Summer" : "Autumn";
case 10:
case 11:
    season = "Autumn";
    break;
case 12:
    season = (d < 21) ? "Autumn" : "Winter";
    break;
default:
    assert("month out of control" == NULL);
    season = "Unknown - invalid month";
    break;
}
printf("The season is %s.\n", season);
cqoc49vn

cqoc49vn3#

“有没有办法仍然用switch语句来做呢?
这个问题表明了一个有缺陷的观点。算法应该被写得清楚和干净地达到任务的目标;不是为了符合 * favorite * 方案而编写的。如其他答案所示,switch()对于解决这个问题来说要么很麻烦,要么没有必要。
值得注意/学习的是,“分支”在处理时间方面可能是昂贵的。虽然if/else条件语句的阶梯可能对人类来说很容易阅读和理解,但找到一个不涉及分支的上级的算法可能会处理得更快。
如果你想 * 计算 * 季节的名称,而不是在条件句中使用大量的 * 魔术数字 *,那么这似乎是可行的。
第一个
而且,只有“月和日”,“闰年”的唯一指示将是如果你有一对“02/29”。不确定你想要什么...

编辑:

不要忘记那些生活在赤道以南的人,这里是对上述函数的微不足道的修改,它采用了第三个参数(对南半球来说是正确的)。

void season( bool SthHemi, uint16_t m, uint16_t d ) {
    char *seasons[] = { "Winter", "Spring", "Summer", "Autumn", "Winter", "Spring", "Summer", };

    char *p = seasons[ (SthHemi*2) + ((m-1) / 3) + (!(m%3)*( d >= 22 )) ];
    printf( "mon %d day %d = %s\n", m, d, p );
}

编辑2:

不太满意季节名称的额外示例,这里有一个改进的计算,它确定使用哪个字符串。

char *season( int SthHemi, uint16_t m, uint16_t d ) {
    char *seasons[] = { "Winter", "Spring", "Summer", "Autumn" };

    return seasons[ (((m+(SthHemi*6)-1) / 3) + (!(m%3)*( d >= 22 )))%4 ];
}

SthHemi-为0(北)或1(南)-乘以6,因为半球的季节相差6个月。将其与月份索引(1-12)相加,减去1,然后除以3,得到要使用的字符串的索引为0,1,2,3或2,3,4,5。现在,如果月份模3为0(即:三月、六月、九月或十二月),使用!0(即:1)乘以日期大于等于22的真值。此操作可能会将1加到目前为止为那些“过渡”月份的最后几天计算的索引值上。最后,使用模4将较大的索引值“ Package ”到0-3的范围内,并从季节名称字符串数组中返回相应的字符串。简单!

相关问题