最稳妥方法是用 std::accumulate 计算总和后转 double 再除以元素个数,初始值用 0.0,n 转 double,空数组需提前判断避免除零。

用 std::accumulate 加 double 除法最稳妥
直接用整数除法会截断小数,哪怕数组元素全是 int,平均值也该用 double 存。推荐组合:std::accumulate 算总和,再转成 double 除以元素个数。
-
std::accumulate默认返回与初始值类型一致的和,所以初始值写0.0比0更安全 - 数组长度必须转为
double或static_cast<double>(n)</double>,否则int / int → int - 空数组要单独判断,否则除零未定义行为(
std::accumulate本身不报错,但除法崩)
int arr[] = {1, 2, 3, 4, 5};
size_t n = sizeof(arr) / sizeof(arr[0]);
if (n == 0) return 0.0;
double avg = std::accumulate(arr, arr + n, 0.0) / n;
手写循环比 std::accumulate 更易控制边界
尤其在嵌入式或禁用 STL 的场景下,手动累加反而更清晰,还能顺便处理溢出或 NaN。
- 累加变量类型建议用
long long(对int数组)或double(对浮点数组),避免中间和溢出 - 循环前检查
n > 0,不满足直接返回NaN或抛异常,别让后续除法失控 - 如果数组是
std::vector,用.data()和.size()替代裸指针计算
double avg = 0.0;
if (n > 0) {
long long sum = 0;
for (size_t i = 0; i (sum) / n;
}
用 std::valarray 只适合固定大小且需批量运算的场景
std::valarray 自带 sum() 方法,但实际项目中极少用——它不兼容 STL 算法,不能用 auto 推导长度,且多数编译器优化不如手写循环。
- 仅当已用
valarray存数据、且需配合shift/apply做向量化运算时才考虑 -
sum()返回类型和元素类型一致,仍需显式转double - 不支持 C 风格数组直接构造,得先拷贝
std::valarray<int> v(arr, n); double avg = v.size() ? static_cast<double>(v.sum()) / v.size() : 0.0;</double></int>
常见错误:用 sizeof(arr) 算长度传进函数就失效
函数参数里 int arr[] 实际是 int*,sizeof(arr) 得到指针大小(通常 8),不是数组总字节。这是新手掉得最多的一个坑。
- 函数内无法靠
sizeof恢复数组长度,必须额外传size_t n - 用模板推导长度只适用于函数模板 + 实参为真实数组(非指针),且调用点必须可见定义
- 现代写法优先用
std::span<int></int>(C++20)或std::vector,自带.size()
比如这个函数一定错:
double bad_avg(int arr[]) {
return std::accumulate(arr, arr + sizeof(arr)/sizeof(*arr), 0.0) / (sizeof(arr)/sizeof(*arr));
} 因为 sizeof(arr) 在函数内永远是 8。
空数组和整数溢出是两个最常被跳过的点,前者导致崩溃,后者导致结果错得离谱但不报错。C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











