在C++中,普通数组是固定长度的,标准库类型vector可理解为可扩充数组(即长度不固定)。

编译参数:g++ --std=c++2a

vector数组的初始化

初始化vector对象的方法方法说明
vector v1v1是一个空vector,它潜在的元素是T类型的,执行默认初始化
vector v2(v1)v2中包含v1所有元素的副本
vector v2 = v1等价于v2(v1),v2中包含v1所有元素的副本
vector v3(n, val)v3包含了n个重复的元素,每个元素的值都是val
vector v4(n)v4包含了n个重复地执行了值初始化的对象
vector v5{a, b, c…}v5包含了初始值个数的元素,每个元素被赋予相应的初始值
vector v5 = {a, b, c…}等价于v5{a, b, c…}

C++11新标准还提供了列表初始化。用花括号括起来的0个或多个初始元素值被赋给vector对象:

vector<string> articles = {"a", "an", "the"};

通常情况下,可以只提供vector对象容纳的元素数量而不用略去初始值。此时库会创建一个值初始化的元素初值,该值由元素类型决定:

  • 元素是内置类型,使用默认值
  • 元素是类类型,元素由类默认初始化
  • 如果元素的类型不支持默认初始化,则必须明确提供初始值
  • 只提供元素数量而没有设定初始值,只能使用直接初始化
vector<int> v1(10);        //v1有10个元素,每个元素的值都是0
vector<int> v2{10};        //v2有1个元素:10

vector<int> v3(10, 1);    //v3有10个元素,每个元素的值都是1
vector<int> v4{10, 1};    //v4有2个元素:10和1

圆括号提供的值用来构造vector对象;花括号的值作为元素的值,执行列表初始化。

如果初始化使用花括号但是提供的值又不能用来列表初始化,就会考虑用这样的值来构造对象。

vector<string> v5{"hi"};    //列表初始化,v5有1个元素
vector<string> v6("hi");    //错误:不能用字符串字面值构建vector对象
vector<string> v7{10};        //v7有10个默认初始化的元素
vector<string> v8{10, "hi"};//v8有10个值为“hi”的元素

普通数组的初始化

默认初始化,变量没有指定处值将被赋予默认值,由变量类型决定,且受定义变量位置影响:

  • 定义于任何函数体之外的变量被初始化为0
  • 函数体内部的内置类型变量不被初始化,未被初始化的内置类型变量的值是未定义的

全局作用域

位于全局作用域的数组没有赋初值时,都默认初始化成0。

#include <iostream>
#include <vector>

using std::cin;
using std::cout;
using std::vector;
using std::endl;

int a[10];
int b[10][10];

int main(int argc, char* argv[]){    
    cout << "测试一维数组" << endl;
    for(int i=0; i<10; i++)cout << a[i] << ' ';
    cout << endl;
    cout << "测试二维数组" << endl;
    for(int i=0; i< 10; i++){
        for(int j=0; j < 10; j++){
            cout << b[i][j] << ' ';
        }
        cout << endl;
    }
    
    return 0;
}

运行结果:

测试一维数组
0 0 0 0 0 0 0 0 0 0 
测试二维数组
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 

局部作用域

函数体内部的内置类型变量不被初始化,未被初始化的内置类型变量的值是未定义的

#include <iostream>
#include <vector>

using std::cin;
using std::cout;
using std::vector;
using std::endl;


int main(int argc, char* argv[]){
    // int a[10]= {0};
    // int b[10][10]= {0};
    int a[10];
    int b[10][10];    
    cout << "测试一维数组" << endl;
    for(int i=0; i<10; i++)cout << a[i] << ' ';
    cout << endl;
    cout << "测试二维数组" << endl;
    for(int i=0; i< 10; i++){
        for(int j=0; j < 10; j++){
            cout << b[i][j] << ' ';
        }
        cout << endl;
    }
    
    return 0;
}

运行结果

测试一维数组
0 0 0 0 8 0 4199705 0 8 0 
测试二维数组
6421704 0 1875947768 0 1875947560 0 1875947840 0 1875946976 0 
1875893184 0 1875947560 0 6421704 0 1875947560 0 1875855620 0 
1875947768 0 1875865606 0 1875947552 0 1875746568 0 3 0 
1875937088 0 13959168 0 1875947560 0 1875942272 0 1875865824 0 
39 0 1875208332 0 13960008 0 268501009 0 13961056 0 
-747787642 32767 4206232 0 0 0 4200108 0 16 0 
0 0 0 0 8 0 4199705 0 4206232 0 
4206224 0 13983824 0 16 0 0 0 4200188 0 
4199744 0 8 0 0 0 268501009 0 13961064 0 
-747787642 32767 8 0 0 0 4200304 0 24 0

列表初始化后:

#include <iostream>
#include <vector>

using std::cin;
using std::cout;
using std::vector;
using std::endl;


int main(int argc, char* argv[]){
    int a[10]= {0};
    int b[10][10]= {0};
    // int a[10];
    // int b[10][10];    
    cout << "测试一维数组" << endl;
    for(int i=0; i<10; i++)cout << a[i] << ' ';
    cout << endl;
    cout << "测试二维数组" << endl;
    for(int i=0; i< 10; i++){
        for(int j=0; j < 10; j++){
            cout << b[i][j] << ' ';
        }
        cout << endl;
    }
    
    return 0;
}

运行结果

测试一维数组
0 0 0 0 0 0 0 0 0 0 
测试二维数组
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0

按道理二维数组这样初始化只能初始化第一行,但是结果却复现不出来,但还是记录下比较稳妥的方法

//最简单粗暴的方法就是逐个赋值,我就不写了
int* b[10];
for(int i=0; i< 10; i++)b[i] = new int[10]{0};
...
for(int i=0; i< 10; i++)delete[] b[i];