闰年判断的正确规则是:能被4整除但不能被100整除,或者能被400整除;c++中需手动实现,推荐写法为return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);,注意输入校验、constexpr优化及跨世纪边界测试。

闰年判断的数学规则必须严格套用
C++ 里没有内置的 is_leap_year() 函数,得自己写逻辑。核心是格里高利历(公历)规则:能被 4 整除但不能被 100 整除,或者能被 400 整除的年份才是闰年。别漏掉“或者能被 400 整除”这一条,否则 2000 年会判错,1900 年也会判错。
常见错误是写成:(year % 4 == 0) —— 这会让 1900、2100 等非闰年误判为闰年。
推荐的 C++ 实现方式(int 参数,返回 bool)
最清晰、不易出错的写法是直接翻译数学定义,用括号明确优先级:
bool is_leap_year(int year) {
return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}
注意点:
-
year应该是正整数;C++ 标准库不保证对负年份(如公元前)有定义,历史年份需自行约定处理方式 - 避免用
year % 400 == 0单独判断——虽然它覆盖了所有能被 400 整除的年份,但漏掉了像 2024 这种只满足前半条件的闰年 - 如果用在日期类中,建议把该函数声明为
constexpr,方便编译期计算:constexpr bool is_leap_year(int year)
用 std::chrono 能绕过手写逻辑吗?
不能。C++20 的 std::chrono 提供了 year_month_day 和 year 类型,但 year 本身没有 is_leap() 成员函数。你可以这样间接验证:
std::chrono::year y{2024};
auto feb_last = std::chrono::year_month_day{y/std::chrono::month{2}/std::chrono::day{29}};
// 如果 2 月 29 日合法,那 year 就是闰年 —— 但这只是运行时试探,不推荐用于判断逻辑
这种写法效率低、可读性差,且依赖日历系统实现细节。不如直接用上面那个三行逻辑。
容易被忽略的边界情况
闰年判断看似简单,但实际工程中常踩坑:
- 输入校验缺失:传入
0、负数、或极大值(如INT_MAX)时,%运算仍有效,但语义上无意义;建议加断言或文档说明有效范围(如 1–9999) - 跨世纪年份:1900、2100 是典型反例,务必单独测一下
- 嵌入式或旧编译器环境:某些平台对负数取模结果不一致(C++11 起已规定向零取整),所以确保
year是非负整数更稳妥
真正难的不是写对一行表达式,而是想到什么时候该检查输入、什么时候该加 constexpr、以及为什么 1900 年必须错——这些地方才容易出线上问题。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











