数值限制与溢出行为
查询 std::numeric_limits,并理解有符号和无符号整数的溢出规则
数值限制与溢出行为 是 CoddyKit 上的免费 C++ Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 C++ Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 C++ Academy 课程共包含 4 节课。
为什么边界很重要
每种数值类型都有可表示的最大值和最小值。超出这些边界可能会悄悄产生错误结果,甚至导致未定义行为。
std::numeric_limits
使用 <limits> 头文件查询任何数值类型的边界。这些是编译时常量,不会产生运行时开销。
#include <limits>
std::cout << std::numeric_limits<int>::max() << "\n";
std::cout << std::numeric_limits<int>::min() << "\n";
std::cout << std::numeric_limits<double>::epsilon();常用查询
最实用的成员包括:
max()— 最大值min()— 最小的正值lowest()— 最小值epsilon()— 最小的有意义差值(浮点数)digits10— 有保证的十进制位数
有符号整数溢出
有符号整数溢出属于未定义行为。编译器可能会假定它永远不会发生,从而进行令人意外的优化。
int x = std::numeric_limits<int>::max();
x += 1; // UB — anything can happen无符号整数回绕
无符号整数溢出是已定义的:数值会按 2^N 取模后回绕。这有时很有用,但也经常是容易踩坑的陷阱。
unsigned int u = 0;
u -= 1; // wraps to 4,294,967,295 (UINT_MAX)浮点数溢出和下溢
浮点数溢出时会变为 inf,而不会导致程序崩溃。下溢时会变为非规格化数或 0。
double x = 1e308;
x *= 100;
std::cout << x; // inf安全地检测溢出
对于有符号整数,请在执行运算前进行检查。编译器提供了内置的算术检查辅助函数,例如 GCC/Clang 中的 __builtin_add_overflow。
if (a > std::numeric_limits<int>::max() - b) {
// overflow would happen
}
int sum = a + b;C++20 的 std::ssize 和 std::cmp_less
C++20 在 <utility> 中新增了安全的整数比较辅助函数:std::cmp_equal、cmp_less、cmp_greater。它们可以正确处理有符号数和无符号数的混合比较。
隐式转换很隐蔽
在比较中混合使用有符号数和无符号数时,有符号操作数会被悄悄转换为无符号数,这是产生细微错误的常见原因。
int a = -1;
unsigned int b = 1;
if (a < b) std::cout << "yes";
else std::cout << "no"; // prints "no"!编译时检查
编写可移植代码时,请使用 static_assert 强制检查对大小的假设。
static_assert(sizeof(int) >= 4, "Need at least 32-bit int");消毒器有助于测试
使用 -fsanitize=undefined 进行构建,可以在测试期间于运行时捕获有符号整数溢出。
g++ -fsanitize=undefined -O1 main.cpp快速检查
在 C++ 中,有符号整数加法发生溢出时会怎样?
回顾
使用 std::numeric_limits 查询类型边界。有符号整数溢出是未定义行为;无符号整数会回绕。混合使用有符号数和无符号数时务必谨慎。消毒器和 C++20 的安全比较函数有助于保护代码。
常见问题解答
「数值限制与溢出行为」课时是免费的吗?
是的 — 「数值限制与溢出行为」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 C++ Academy 课程的其余内容,请升级到 CoddyKit PRO。 C++ Academy 课程共包含 4 节课。
「数值限制与溢出行为」这节课中我会学到什么?
查询 std::numeric_limits,并理解有符号和无符号整数的溢出规则 你通过在浏览器中直接运行的动手代码来练习 C++ Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 C++ Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 C++ Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。
「数值限制与溢出行为」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 C++ Academy 课中编写并运行代码吗?
能。每节 C++ Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。