0Pricing
C++ Academy · 课时

数值限制与溢出行为

查询 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 反馈 — 无需本地设置。

此课程中的所有课时

  1. 整数类型与浮点类型
  2. cmath 头文件:pow、sqrt、abs、round
  3. 使用 random 头文件生成随机数
  4. 数值限制与溢出行为
← 返回 C++ Academy