跳至正文
View Categories

5 min read

1. 什么是数组 #

“数组”,简单来说,就是“一组数”排成一列。

来看一些生活中的“数组”

这里,要注意的就是最后一个例子,这是 bool 变量组成的数组。下面有详细说明。

1.1 定义 #

如何定义一个数组呢?和定义字符串类似:

#include <iostream>
using namespace std; 
int main()
{
    int value_a;    // 定义 int 类型的变量

    int array_a[];  // 定义 int 类型的数组的变量

    return 0;
}

特别注意:
和一般变量定义的差别,在于中括号[ ];
有中括号[ ],就是数组;
中括号[ ],写在变量的后面;

1.2 初始化 #

1.2.1 基本写法 #

#include <iostream>
using namespace std; 
int main()
{
    int array_a[] = {0, 1, 2, 3, 4};  // 初始化为 0, 1, 2, 3, 4

    return 0;
}

特别注意:
初始化,使用大括号{ }

1.2.2 三种变体 #

#include <iostream>
using namespace std;
int main()
{
    int array_a0[]  = {};         // 初始化为 空
    int array_a1[3] = {};         // 初始化为 0,0,0
    int array_a2[3] = {1,2,3};    // 初始化为 1,2,3
    int array_a2[3] = {1,2};      // 初始化为 1,2,0
    int array_a2[3] = {1,2,3,4};  // 【错误】指定的数组长度为 3,但是却使用了 4 个值来初始化。

    return 0;
}

特别注意:
中括号[ ]中的数值,表示数组的长度
大括号{ }中的数值,表示数组的内容;注意,使用逗号(,)分隔。
中括号[ ]中的数值(长度)应该 不小于 大括号{ }中数值的数量(内容数量)。

1.3 读 #

与字符串一样,索引符号依然使用的是 [ ]
请看代码:

#include <iostream>
using namespace std; 
int main()
{
    int arr[] = {8848, 8611, 7556, 6860, 7810};
    for(int i = 0; i < 4; i++) 
        cout << arr[i] << endl;   // 循环输出数组中的所有元素

    return 0;
}

在使用索引时,要特别注意“数组越界”错误,也就是访问到内存中不属于数组的区域

数组的索引 ID 必须在 [0, 元素数量) // ID 的取值,包含 “0” ,不包含“元素数量”
数组的索引 ID 不可以是负数

1.4 写 #

#include <iostream>
using namespace std;
int main()
{
    int arr[] = {8848, 8611, 7556, 6860, 7810};
    for(int i = 0; i < 4; i++) 
        arr[i] = arr[i]+10;      // 修改数组中的元素

    return 0;
}

2. 数组的遍历 #

2.1 如何读取数组的长度 #

假设有一个很长的数组,如何获得它的长度呢?

int a [] = {1,4,5,9,15,125,12,12,1,12,14,15,48,787,7,9,9,954,65,32,21,
    45,2,9,15,12,1255,12,12,182,9,15,12,125,58,42,9,15,5,12,12,15,12,12,
    15,12,12,15,12,12,15,12,12,15,12,12,15,12,12,15,12,12,15,12,12,15,12,
    12,15,12,12,15,12,12,15,12,12,15,12,12,112,1215,12,12,1,2,9,15,12,1585,
    12,12,12,9,152,14,155,12,12,1582,9,15,48,78,0,7,8,9,15,12,9,2,12,9,15,
    12,122,125,12,12,1,9,15,12,124,15,48,72,9,15,12,1282,9,15,12,125,12,12,15,12};    

换一个问题,小王花了 10 块钱买包子,每个包子 2 元钱,请问他买了几个包子?

类似的,假如我们知道了数组的总大小,也知道数组中一个元素的大小,那么就可以计算出数组中的元素数量了。
在字符串一节中,我们讲解过字符串长度的求法。数组的长度也类似,只不过,数据的末尾没有自动添加的’/0′

请试一试,输出上面数组 a 的大小。

/*
    请完成后,查看示例程序




*/

请看代码

#include <iostream>
using namespace std;
int main()
{
    int arr [] = {1,4,5,9,15,125,12,12,1,12,14,15,48,787,7,9,9,954,65,32,21,
        45,2,9,15,12,1255,12,12,182,9,15,12,125,58,42,9,15,5,12,12,15,12,12,
        15,12,12,15,12,12,15,12,12,15,12,12,15,12,12,15,12,12,15,12,12,15,12,
        12,15,12,12,15,12,12,15,12,12,15,12,12,112,1215,12,12,1,2,9,15,12,1585,
        12,12,12,9,152,14,155,12,12,1582,9,15,48,78,0,7,8,9,15,12,9,2,12,9,15,
        12,122,125,12,12,1,9,15,12,124,15,48,72,9,15,12,1282,9,15,12,125,12,12,15,12};   

    int size = sizeof(arr) / sizeof(int);

    // 注意,sizeof(int) 可以替换为 sizeof(arr[0])

    cout << "size = " << size << endl;
    return 0;
} 

2.1 遍历数组元素 #

这是一种重要的程序结构,请掌握。
请试一试,使用 while 和 for 遍历下面数组。

    int arr [] = {1,4,5,9,15,125,12,12,1,12,14,15,48,78,12,12,15,12};  
/*
    请完成后,查看示例程序




*/

请看代码

#include <iostream>
using namespace std;
int main()
{
    int arr [] = {1,4,5,9,15,125,12,12,1,12,14,15,48,78,12,12,15,12};    
    int size = sizeof(arr) / sizeof(int);


    // while
    int i(0);
    cout << "Using while: " << endl;
    while (i < size)
        cout << arr[i++];
    cout << endl << endl;


    // for 1 
    cout << "Using for 1: " << endl;
    for (int j = 0; j < size; j++)
        cout << dashima[j];
    cout << endl << endl;


    // for 2
    cout << "Using for 2: " << endl;
    for (int j = 0; j < size; )
        cout << dashima[j++];
    cout << endl << endl;


    return 0;
} 

3. 数组的复制、拼接、裁剪、选择 #

在 C++ 中,数组的长度是固定的。
也就是说,一旦定义好数组以后,就不能在改变数组的大小

3.1 数组的复制 #

复制数组,只可以使用 逐个复制 的方式进行。

试一试:
假设数组 a 为 {1, 2, 3, 4},请定义合适大小的数组 c,并将 a 复制到 c。

/*
    请完成后,查看示例程序




*/

示例代码:

#include <iostream>
using namespace std;
int main()
{
    // 将 a 复制到 c
    int a[] = {1, 2, 3, 4};
    int c[4] = {};          // 必须在复制前,根据 a 的大小,初始化 c

    int size = sizeof(a)/sizeof(a[0]);
    for(int i = 0; i < size; i++)
    {
        c[i] = a[i];        // 逐个复制
    }

    return 0;
}

3.2 数组的拼接 #

数组拼接,指的是将{1, 2, 3}和{4, 5}合并成{1, 2, 3, 4, 5}这样的操作。
需要使用复制来完成。

试一试:
假设数组 a 为 {1, 2, 3},b 为 {4, 5},请定义合适大小的数组 c,存放 a 和 b 拼接后的结果。

/*
    请完成后,查看示例程序




*/

示例代码:

#include <iostream>
using namespace std;
int main()
{
    // 将 a 和 b 拼接成 c
    int a[] = {1, 2, 3};
    int b[] = {4, 5};
    int c[5] = {};               // 在初始化的时候,需要确定 c 的大小


    // 先复制 a
    int sizeA = sizeof(a)/sizeof(a[0]);
    for(int i = 0; i < sizeA; i++)
    {
        c[i] = a[i];             // 逐个复制
    }


    // 再复制 b
    int sizeB = sizeof(b)/sizeof(b[0]);
    for(int i = 0; i < sizeB; i++)
    {
        c[sizeA + i] = b[i];     // 逐个复制,请注意这里 c 的 ID 变化。B 的元素要排列在 A 之后。
    }


    return 0;
}

3.3 数组的裁剪 #

裁剪,就是指删除数组中的指定元素。
这里有两种,第一是按区间裁剪,第二是给定序号裁剪。

3.3.1 按区间裁剪 #

试一试:
假设数组 a 为 {1,2,3,4,5,6,7,8,9},请裁剪第2到第4个元素(序号从 0 开始,第2和第4均不保留),将剩下的元素,保留在 c 中。

/*
    请完成后,查看示例程序




*/

示例代码:

#include <iostream>
using namespace std;
int main()
{
    int a[] = {1,2,3,4,5,6,7,8,9};

    // 确定删除后的数组大小 = 9-3 = 6
    int c[6] = {};                      // 在初始化的时候,需要确定 c 的大小
                                        // 【注意】中括号中,不可以填变量,这里要写数字或者常量(常量将在后续讲解)。


    int sizeA = sizeof(a)/sizeof(a[0]);
    int id_c = 0;                       // 请注意 c 的 id 变化
    for(int i = 0; i < sizeA; i++)
    {
        // 创建裁剪规则
        if(2 <= i && i <= 4)            // 跳过第2到第4个元素
            continue;

        c[id_c] = a[i];                 // 逐个复制
        id_c++;                         // id_c 只在 c 被赋值后,才偏移一位
    }

    return 0;
}

同学们可以思考一下:
上面代码中的

    c[id_c] = a[i];                 
    id_c++;

等价于

    c[id_c++] = a[i];                 

3.3.2 给定序号裁剪 #

试一试:
假设数组 a 为 {1,2,3,4,5,6,7,8,9},请裁剪序号为{0,5,6,7}的元素,将剩下的元素,保留在 c 中。

/*
    请完成后,查看示例程序




*/

示例代码:

#include <iostream>
using namespace std;
int main()
{
    int a[] = {1,2,3,4,5,6,7,8,9};

    // 确定删除后的数组大小 = 9-4 = 5
    int c[5] = {};                      // 在初始化的时候,需要确定 c 的大小
                                        // 【注意】中括号中,不可以填变量,这里要写数字或者常量(常量将在后续讲解)。


    int sizeA = sizeof(a)/sizeof(a[0]);
    int id_c = 0;                       // 请注意 c 的 id 变化
    for(int i=0; i < sizeA; i++)
    {
        // 创建裁剪规则
        if(i == 0 || i == 5 || i == 6 || i == 7) 
            continue;                   // 跳过序号为{0,5,6,7}的元素

        c[id_c] = a[i];                 // 逐个复制
        id_c++;                         // id_c 只在 c 被赋值后,才偏移一位
    }

    return 0;
}

3.4 数组的选择 #

选择,就是指保留数组中的指定元素。其实这个和裁剪数组是类似的操作,只不过正好是相反的过程。
裁剪:保留未被指定的元素
选择:保留被指定的元素
这里有两种,第一是按区间选择,第二是给定序号选择。

3.4.1 按区间选择 #

试一试:
假设数组 a 为 {1,2,3,4,5,6,7,8,9},选择第2到第4个元素(序号从 0 开始,第2和第4均不保留),保留在 c 中。

/*
    请完成后,查看示例程序




*/

示例代码:

#include <iostream>
using namespace std;
int main()
{
    int a[] = {1,2,3,4,5,6,7,8,9};

    // 确定删除后的数组大小 = 3
    int c[3] = {};                      // 在初始化的时候,需要确定 c 的大小
                                        // 【注意】中括号中,不可以填变量,这里要写数字或者常量(常量将在后续讲解)。


    int sizeA = sizeof(a)/sizeof(a[0]);
    int id_c = 0;                       // 请注意 c 的 id 变化
    for(int i = 0; i < sizeA; i++)
    {
        // 创建选择规则
        if(2 <= i && i <= 4)            // 保留第2到第4个元素
        {
            c[id_c] = a[i];             // 逐个复制
            id_c++;                     // id_c 只在 c 被赋值后,才偏移一位
        }
    }

    return 0;
}

3.3.2 给定序号选择 #

试一试:
假设数组 a 为 {1,2,3,4,5,6,7,8,9},请选择序号为{0,5,6,7}的元素,保留在 c 中。

/*
    请完成后,查看示例程序




*/

示例代码:

#include <iostream>
using namespace std;
int main()
{
    // 将 a 和 b 拼接成 c
    int a[] = {1,2,3,4,5,6,7,8,9};

    // 确定删除后的数组大小 = 4
    int c[4] = {};                      // 在初始化的时候,需要确定 c 的大小
                                        // 【注意】中括号中,不可以填变量,这里要写数字或者常量(常量将在后续讲解)。


    int sizeA = sizeof(a)/sizeof(a[0]);
    int id_c = 0;                       // 请注意 c 的 id 变化
    for(int i = 0; i < sizeA; i++)
    {
        // 创建选择规则                  // 保留序号为{0,5,6,7}的元素
        if(i == 0 || i == 5 || i == 6 || i == 7) 
        {
            c[id_c] = a[i];             // 逐个复制
            id_c++;                     // id_c 只在 c 被赋值后,才偏移一位
        }
    }

    return 0;
}