在刷 LeetCode 的过程中,经常会遇到各种数组初始化写法,例如:
int arr[] = {1, 2, 3};
vector<int> v(5);
vector<int> v = {1, 2, 3};
这些写法看起来非常相似,但实际含义并不完全相同。
尤其是 vector 中 () 和 {} 的区别,如果没有搞清楚,很容易出现编译错误或者初始化结果与预期不同的问题。
本文整理一下 C++ 中常见的数组初始化方式,重点介绍原生数组和 vector。
一、C++中的数组主要分为两类
在 C++ 中,我们平时说的“数组”实际上可能指两种东西:
-
原生数组(Built-in Array)
-
std::vector
例如:
int arr[5];
这是 C++ 的原生数组。
而:
vector<int> v;
是 STL 中的动态数组 vector。
两者都可以用来保存一组数据,但是初始化方式和使用方式存在一些区别。
二、原生数组的初始化
1. 不指定大小,直接使用初始化列表
int arr[] = {1, 2, 3, 4};
这里没有指定数组大小。
编译器会根据初始化列表中的元素数量自动推断数组大小。
相当于:
int arr[4] = {1, 2, 3, 4};
最终:
arr[0] = 1
arr[1] = 2
arr[2] = 3
arr[3] = 4
这是原生数组非常常见的一种初始化方式。
2. 指定大小,同时初始化
int arr[4] = {1, 2, 3, 4};
这里明确指定数组大小为 4,同时提供 4 个初始值。
结果:
[1, 2, 3, 4]
3. 只初始化一部分元素
例如:
int arr[5] = {1, 2};
虽然数组有 5 个元素,但是只提供了两个初始值。
没有提供初始值的元素会被初始化为 0。
因此最终结果是:
[1, 2, 0, 0, 0]
这一点在 C++ 中非常常见。
4. 将整个数组初始化为 0
可以写:
int arr[5] = {};
结果:
[0, 0, 0, 0, 0]
这种写法非常简洁。
例如:
int count[100] = {};
可以创建一个长度为 100、所有元素初始值都是 0 的数组。
5. 创建数组后再逐个赋值
也可以先创建数组:
int arr[3];
arr[0] = 10;
arr[1] = 20;
arr[2] = 30;
最终:
[10, 20, 30]
这种方式适合需要根据程序运行过程动态计算每个元素的情况。
三、vector的初始化
在 LeetCode 等算法题中,我们更加经常使用:
vector<int>
因此,vector 的初始化方式尤其值得掌握。
1. 创建一个空 vector
vector<int> v;
此时 v 中没有任何元素:
[]
可以通过 push_back() 添加元素:
v.push_back(10);
v.push_back(20);
v.push_back(30);
最终:
[10, 20, 30]
这种方式非常适合元素数量一开始无法确定的情况。
四、vector指定元素数量
1. vector<int> v(5);
例如:
vector<int> v(5);
这里的 5 表示:
创建一个包含 5 个元素的 vector。
对于 int 类型来说,这些元素会被初始化为 0。
因此:
[0, 0, 0, 0, 0]
可以通过:
v[0] = 10;
v[1] = 20;
修改其中的元素。
2. vector<int> v(5, 10);
还可以同时指定元素数量和初始值:
vector<int> v(5, 10);
含义是:
创建 5 个元素,并且每个元素初始化为 10。
结果:
[10, 10, 10, 10, 10]
这个写法在算法题中非常常见。
例如:
vector<bool> visited(100, false);
表示创建一个包含 100 个元素的 vector,每个元素初始值都是 false。
五、使用初始化列表初始化 vector
还可以直接写:
vector<int> v = {1, 2, 3, 4};
结果:
[1, 2, 3, 4]
也可以省略 =:
vector<int> v{1, 2, 3, 4};
结果完全一样:
[1, 2, 3, 4]
这种 {} 写法叫做列表初始化(List Initialization)。
六、最容易混淆的地方:() 和 {}
这是学习 vector 初始化时最需要注意的地方。
看下面两个代码:
vector<int> v(3);
和:
vector<int> v = {3};
它们看起来很像,但含义完全不同。
vector<int> v(3);
表示:
创建 3 个元素。
结果:
[0, 0, 0]
vector<int> v = {3};
表示:
创建一个元素,这个元素的值是 3。
结果:
[3]
所以:
vector<int> v(3);
不是 [3]。
而是:
[0, 0, 0]
七、一个更加容易混淆的例子
比较:
vector<int> v(3, 5);
和:
vector<int> v{3, 5};
它们的结果完全不同。
第一种
vector<int> v(3, 5);
表示:
创建 3 个元素,每个元素都是 5。
结果:
[5, 5, 5]
第二种
vector<int> v{3, 5};
表示:
使用 3 和 5 两个元素进行初始化。
结果:
[3, 5]
所以一定要注意:
v(3, 5)
和:
v{3, 5}
不是一回事。
八、一次实际的 LeetCode 报错
在刷 LeetCode 的时候,我遇到过这样的代码:
vector<double> ans(2) = {
celsius + 273.15,
celsius * 1.8 + 32.0
};
编译器报错:
error: expected ';' at end of declaration
乍一看很容易以为是分号的问题。
实际上,真正的问题是:
vector<double> ans(2) = {...};
这种声明方式本身就是非法的 C++ 语法。
不能把:
vector<double> ans(2);
和:
vector<double> ans = {a, b};
这两种初始化方式直接拼在一起。
九、正确写法一:使用初始化列表
如果希望直接创建:
[a, b]
应该写:
vector<double> ans = {
a,
b
};
例如温度转换:
vector<double> convertTemperature(double celsius) {
vector<double> ans = {
celsius + 273.15,
celsius * 1.8 + 32.0
};
return ans;
}
十、正确写法二:先创建,再通过下标赋值
也可以写成:
vector<double> convertTemperature(double celsius) {
vector<double> ans(2);
ans[0] = celsius + 273.15;
ans[1] = celsius * 1.8 + 32.0;
return ans;
}
这里:
vector<double> ans(2);
先创建两个元素:
[0, 0]
然后:
ans[0] = ...
ans[1] = ...
逐个修改。
这种写法对于刚开始学习 C++ 的人来说非常直观。
十一、正确写法三:直接返回初始化列表
如果代码比较熟练,还可以直接:
vector<double> convertTemperature(double celsius) {
return {
celsius + 273.15,
celsius * 1.8 + 32.0
};
}
因为函数的返回类型已经明确是:
vector<double>
所以 C++ 可以根据返回类型构造对应的 vector。
十二、size 和 capacity 不要混淆
还有一个容易出现的概念错误。
例如:
vector<int> v(5);
这里的 5 表示的是:
size,也就是当前元素数量。
因此:
v.size()
结果是:
5
而 capacity() 表示 vector 当前已经分配的存储空间能够容纳多少元素。
例如:
v.capacity()
可能得到:
5
也可能得到一个大于 5 的值。
因此:
size → 当前有多少个元素
capacity → 当前分配的空间最多可以容纳多少元素
两者不是一个概念。
十三、常见初始化方式总结
可以把最常用的写法总结成下面这张表:
| 写法 | 含义 | 示例结果 |
|---|---|---|
vector<int> v; | 创建空 vector | [] |
vector<int> v(5); | 创建 5 个元素 | [0,0,0,0,0] |
vector<int> v(5, 10); | 创建 5 个元素,每个为 10 | [10,10,10,10,10] |
vector<int> v = {1,2,3}; | 使用元素初始化 | [1,2,3] |
vector<int> v{1,2,3}; | 使用列表初始化 | [1,2,3] |
vector<int> v(3); 后 v[i]=... | 先创建再赋值 | 根据赋值结果 |
vector<int> v; 后 push_back() | 动态添加元素 | 根据添加结果 |
十四、刷 LeetCode 时怎么选择?
对于算法题,我建议优先掌握这几种。
需要固定数量、默认值为 0:
vector<int> nums(100);
需要固定数量,并设置统一初始值:
vector<int> nums(100, -1);
已经知道具体有哪些元素:
vector<int> nums = {1, 2, 3, 4};
元素数量不确定:
vector<int> nums;
nums.push_back(1);
nums.push_back(2);
返回几个计算结果:
return {a, b};
十五、最后记住这几个区别
如果只记几个最重要的知识点,可以记下面这些:
vector<int> v(3);
表示:
创建 3 个元素
而:
vector<int> v{3};
表示:
创建 1 个元素,值为 3
再看:
vector<int> v(3, 5);
表示:
创建 3 个元素,每个值为 5
而:
vector<int> v{3, 5};
表示:
创建 2 个元素,分别为 3 和 5
最后,不要写:
vector<int> v(3) = {1, 2, 3}; // ❌
应该根据需求选择:
vector<int> v(3);
或者:
vector<int> v = {1, 2, 3};
总结
C++ 中数组初始化的写法比较多,但在实际刷题过程中,并不需要一开始全部记住。
对于 vector,最重要的是理解:
() → 经常用于指定元素数量/统一初始值
{} → 经常用于直接使用一组具体元素进行初始化
例如:
vector<int> a(5); // 5 个元素
vector<int> b(5, 1); // 5 个 1
vector<int> c{1, 2, 3}; // 3 个具体元素
把这三个区别真正理解之后,LeetCode 中绝大多数 vector 初始化代码就不会再容易混淆了。
1万+



被折叠的 条评论
为什么被折叠?



