在C++编程中,数组的批量初始化是很多场景下都会遇到的需求,传统的循环逐个赋值方式不仅代码冗余,还容易出错。标准库中的fill和iota函数提供了更简洁高效的批量初始化方案,能够覆盖大部分常见的数组初始化场景。

fill函数的基本用法
fill函数定义在<algorithm>头文件中,作用是将指定范围内的所有元素赋值为同一个值,适合需要批量设置相同初始值的场景。
fill函数的语法格式如下:
#include <algorithm>
#include <iostream>
#include <array>
int main() {
// 普通数组初始化
int arr[5];
std::fill(arr, arr + 5, 10); // 将arr[0]到arr[4]都赋值为10
// 动态数组初始化
int* dynArr = new int[5];
std::fill(dynArr, dynArr + 5, 20);
// std::array初始化
std::array<int, 5> stdArr;
std::fill(stdArr.begin(), stdArr.end(), 30);
// 输出验证
std::cout << "普通数组: ";
for (int i = 0; i < 5; i++) {
std::cout << arr[i] << " ";
}
std::cout << std::endl;
std::cout << "动态数组: ";
for (int i = 0; i < 5; i++) {
std::cout << dynArr[i] << " ";
}
std::cout << std::endl;
std::cout << "std::array: ";
for (int num : stdArr) {
std::cout << num << " ";
}
std::cout << std::endl;
delete[] dynArr;
return 0;
}
fill函数的注意事项
- fill函数的前两个参数是迭代器范围,左闭右开,即包含第一个参数指向的元素,不包含第二个参数指向的元素
- 对于自定义类型,需要保证该类型支持赋值操作,否则无法使用fill函数
- 如果初始化范围超过数组实际长度,会导致未定义行为,使用前需要确认范围合法性
iota函数的基本用法
iota函数定义在<numeric>头文件中,作用是将指定范围内的元素依次赋值为递增的序列值,适合需要生成连续递增初始值的场景。
iota函数的语法格式如下:
#include <numeric>
#include <iostream>
#include <vector>
int main() {
// 普通数组初始化
int arr[5];
std::iota(arr, arr + 5, 1); // 从1开始递增赋值,arr变为[1,2,3,4,5]
// vector初始化
std::vector<int> vec(5);
std::iota(vec.begin(), vec.end(), 100); // 从100开始递增,vec变为[100,101,102,103,104]
// 自定义步长场景(结合后续修改)
int arr2[5];
std::iota(arr2, arr2 + 5, 0);
for (int i = 0; i < 5; i++) {
arr2[i] *= 2; // 生成[0,2,4,6,8]的偶数序列
}
// 输出验证
std::cout << "普通数组: ";
for (int i = 0; i < 5; i++) {
std::cout << arr[i] << " ";
}
std::cout << std::endl;
std::cout << "vector: ";
for (int num : vec) {
std::cout << num << " ";
}
std::cout << std::endl;
std::cout << "自定义步长数组: ";
for (int i = 0; i < 5; i++) {
std::cout << arr2[i] << " ";
}
std::cout << std::endl;
return 0;
}
iota函数的注意事项
- iota函数的第三个参数是起始值,后续元素依次在前一个元素基础上加1
- 起始值可以是任意可递增的类型,比如整数、浮点数、枚举类型等,只要该类型支持++运算符
- 同样需要保证迭代器范围合法,避免越界访问
两种函数的适用场景对比
可以通过下表快速判断不同场景下应该选择哪种初始化方式:
| 初始化需求 | 推荐函数 | 优势 |
|---|---|---|
| 所有元素赋值为同一个固定值 | fill函数 | 代码简洁,直接指定目标值即可 |
| 元素需要赋值为连续递增序列 | iota函数 | 无需手动写循环递增,减少出错概率 |
| 元素需要赋值为有规律的序列(如偶数、倍数) | iota+后续修改 | 先生成基础序列再调整,比手动循环更清晰 |
| 初始化范围不固定,依赖运行时计算 | 两者都适用 | 都支持动态传入迭代器范围,灵活度高 |
性能对比
对比传统的for循环逐个赋值、fill函数、iota函数的性能,在数组长度为1000000的测试场景下,三者的耗时差异很小,fill和iota函数由于是标准库优化实现,在部分编译器下甚至比手写循环效率更高,同时代码可读性更好,优先推荐使用这两种标准库函数。
使用fill和iota函数时,记得包含对应的头文件<algorithm>和<numeric>,否则会导致编译错误。