闰年判断必须严格遵循格里高利历规则:能被4整除且不能被100整除,或能被400整除;C++需手动实现,推荐写法为(year % 4 == 0) && (year % 100 != 0) || (year % 400 == 0),注意括号与运算符优先级,避免负数、浮点数及边界问题。

闰年判断的数学逻辑必须严格按规则写
直接用 year % 4 == 0 是错的,C++里没有内置闰年函数,必须手动实现格里高利历规则:能被4整除但不能被100整除,或者能被400整除。
常见错误是漏掉“被100整除但不被400整除则不是闰年”这一层排除,比如1900年会误判为闰年。
-
2000→ 是闰年(满足被400整除) -
1900→ 不是闰年(被100整除但不被400整除) -
2024→ 是闰年(被4整除且不被100整除) -
2023→ 不是闰年(不被4整除)
推荐的C++实现方式:一行布尔表达式
最简洁、无分支、易读、可内联的写法是:
bool is_leap_year(int year) {
return (year % 4 == 0) && (year % 100 != 0) || (year % 400 == 0);
}注意运算符优先级:&& 优先于 ||,括号不能省;如果写成 year % 4 == 0 && year % 100 != 0 || year % 400 == 0 逻辑上也对,但加括号更防误读。
立即学习“C++免费学习笔记(深入)”;
别用 if-else 返回不同值——没必要增加分支,现代CPU对这种纯算术表达式预测效率更高。
容易踩坑的边界情况和类型问题
传入负数年份(如公元前1年)时,C++取模结果依赖编译器符号处理,-1 % 4 可能是 -1 或 3。标准闰年规则只定义于公元后,实际项目中应先断言或限制输入范围。
- 使用
unsigned int能避免负数,但要注意year - 1类操作可能回绕 - 如果年份来自用户输入或文件解析,务必检查是否在合理区间(如
1 ~ 9999) - 不要用
float或double存年份再取模——精度丢失会导致误判
在chrono或第三方库中要不要重写?
C++20 <chrono> 没提供闰年判断接口,std::chrono::year_month_day 构造时会静默截断非法日期(如2月30日),但不会告诉你哪年是闰年。
Boost.Date_Time 有 boost::date_time::is_leap_year(),但引入整个Boost只为一个函数太重。除非项目已重度依赖Boost,否则手写上面那行表达式更轻量、更可控。
真正复杂的是跨历法(儒略历/格里高利历切换年份),比如1752年英国跳过11天——这种场景才需要专用日历库,普通业务代码按标准格里高利规则走就行。


















