<p>应使用 constexpr double PI = 3.14159265358979323846;,避免 M_PI 的平台依赖;半径平方用 r * r 而非 std::pow(r, 2);返回类型明确写 double,不使用 auto。</p>

用 M_PI 还是自己写 3.1415926?
直接用 M_PI 最省事,但得先确认它是否可用——它不是 C++ 标准常量,而是 POSIX 扩展,#define _USE_MATH_DEFINES(Windows)或 #define _GNU_SOURCE(Linux/glibc)必须在 #include <cmath> 前定义,否则编译报错:‘M_PI’ was not declared in this scope。
更稳妥的做法是自己定义:
constexpr double PI = 3.14159265358979323846;
- 避免平台差异和宏定义顺序陷阱
- 用
constexpr保证编译期求值,无运行时开销 - 别用
float类型存 π,精度不够,算半径 1000 的圆面积会丢掉小数点后几位
std::pow(r, 2) 和 r * r 哪个更适合算半径平方?
选 r * r。虽然 std::pow 看起来“语义清晰”,但它为通用幂运算设计,有函数调用开销、浮点异常检查、分支判断,对整数次方纯属杀鸡用牛刀。
-
std::pow(r, 2)可能比r * r慢 3–5 倍(尤其在开启 O2 以下优化时) -
std::pow对int参数会隐式转成double,多一次转换;而r * r类型推导干净 - 如果
r是负数,std::pow(-2.0, 2)虽然结果正确,但某些老 libc 实现可能触发domain error
面积函数该返回 double 还是 auto?
明确写 double。C++ 中面积是连续量,float 在半径稍大时就严重失真,比如 r = 1e6f 时,float 平方后有效数字只剩约 6 位,面积误差可达上万;而 double 能稳住 15 位有效数字。
立即学习“C++免费学习笔记(深入)”;
- 别用
auto推导返回类型——接口不透明,调用方无法预判精度,也妨碍模板特化或重载决策 - 如果输入是
long long r,别直接r * r * PI,先转double(r),否则r * r可能溢出(long long平方易超限) - 不需要加
const或&修饰返回值——double是小对象,按值返回最自然
编译器会不会把 PI * r * r 优化成单条乘法指令?
现代编译器(GCC/Clang ≥ 8,MSVC ≥ 2019)在 -O2 下基本都会把 PI * r * r 合并为两个乘法,并复用中间结果;但前提是 PI 是 constexpr,且 r 不带副作用(比如不是 get_radius() 这种函数调用)。
- 如果写了
return PI * std::pow(r, 2);,编译器通常不会替你拆掉std::pow,优化止步于内联层面 - 调试模式(
-O0)下,所有表达式都老老实实一步步算,别指望优化 - 真正影响性能的往往不是这一行,而是频繁调用该函数却没缓存结果——比如在循环里反复算同一圆的面积
π 的精度、平方的写法、返回类型的显式声明,这三处看着小,但任意一个松动,就可能让结果在边界场景下悄然偏移或崩溃。写完最好拿 r = 1、r = 1e8、r = 0.001 三组数手算验证一下量级和小数位。










