5 数组

5.1 概述

所谓数组,就是一个集合,里面 有序地 存放了 相同类型 的数据元素。

特点1: 数组中的每个数据元素都是相同的数据类型

特点2: 数组中的元素,按顺序排列,在内存中占据一块连续的内存区域,数组名实际上就是这块空间的名称

因为数组名实际上就是内存空间的名称。所以,之间输出数组名,将得到此数组内存空间的起始地址。使用 sizeof 数组名 将得到此数组内存空间的大小。

5.2 一维数组

5.2.1 一维数组的基础定义方式

定义方式:

数据类型 数组名[ 数组长度 ];

说明:

  1. 数组名的命名规范与变量名命名规范一致;数组不要和变量重名。
  2. 声明数组的长度时,不能使用变量。
  3. 在数组定义时,给所有数组元素赋初值,可以省略数组长度。

在C++的标准中,不允许使用变量作为数组长度。但在实际编写C++代码时,编译器可能允许使用。

示例

#define N 10

int main() {
    const int SIZE = 20;
    int size;
    cin>>size;
    int a[50];
    int b[N];
    int c[SIZE];
    int d[size];    //不一定正确
    return 0;
}

5.2.2 使用下标访问一维数组元素

用户需要使用下标运算符([ ])来访问数组的的元素。

语法:

数组名[ 下标 ];

注意: 下标从0开始。

示例

int main() {
	//数据类型 数组名[元素个数];
	int score[10];

	//利用下标赋值
	score[0] = 100;
	score[1] = 99;
	score[2] = 85;

	//利用下标输出
	cout << score[0] << endl;
	cout << score[1] << endl;
	cout << score[2] << endl;

	return 0;
}

5.2.3 一维数组的遍历

依次访问每一个数组元素的过程,叫做数组的遍历。

方法:

  1. 使用for循环访问使用下标
  2. 使用基于范围的 for 语句

示例

#include<iostream>
#include <algorithm>

using namespace std;

int main() {
    int score[3];

    //利用下标赋值
    score[0] = 100;
    score[1] = 99;
    score[2] = 85;

    // 1. 使用for循环访问使用下标
    for (int i = 0; i < 3; i++)
    {
        cout << score[i] << endl;
    }

    // 2. 使用基于范围的 for 语句
    for (int i : score)
    {
        cout << i << endl;
    }

    return 0;
}

5.2.4 一维数组的初始化

在定义数组时,可以对数组元素指定初值,这被称为数组的初始化。

初始化方式:

  1. 不初始化

如果数组为全局变量或静态局部变量,数组所有元素初值为0;如果数组为局部变量,初值为随机值。

#include<iostream>
#include <algorithm>

using namespace std;

int a[3];

int main() {
    int b[3];

    // 数组为全局变量,数组所有元素初值为0
    for (int i : a)
    {
        cout << i << endl;
    }
    
    // 数组为局部变量,数组所有元素初值为随机值
    for (int i : b)
    {
        cout << i << endl;
    }

    return 0;
}
  1. 对所有元素赋初值

语法: 数据类型 数组名[ 数组长度 ] = {值1, 值2,...最后一个元素的值}

注意: 这种情况下,可以省略数组长度。因为编译器可以推测数组长度。

示例:

    // 以下两种方式等价
    int a[10] = {100, 90, 80, 70, 60, 50, 40, 30, 20, 10};
    int b[] = {100, 90, 80, 70, 60, 50, 40, 30, 20, 10};
  1. 对部分元素赋初值

语法: 数据类型 数组名[ 数组长度 ] = {值1, 值2,...}

注意: 这种情况下,值被依次分配,未能分配到初值的元素,将被赋初值0。

示例:

int main() {
    int a[10] = {100};

    for (int i: a) {
        cout << i << endl;
    }

    return 0;
}

5.2.5 一维数组案例

案例:从键盘输入数组中的每个元素的值,然后获取数组中的最大值。

参考代码:

int main() {
    int a[5];

    // 输入每个元素的值
//    这种基于范围的for语句,不可以实现输入效果
//    for (int i: a) {
//        cin >> i;
//    }
//    这种基于范围的for语句,可以实现输入效果
//    for (int & i: a) {
//        cin >> i;
//    }

    // 现在会这种方式就可以
    for (int i = 0; i < 5; ++i) {
        cin >> a[i];
    }
    
    int max = 0;

    for (int i: a) {
        max = max > i ? max : i;
    }

    cout << max << endl;

    return 0;
}

5.2.6 冒泡排序

作用: 最常用的排序算法,对数组内元素进行排序

  1. 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
  2. 对每一对相邻元素做同样的工作,执行完毕后,找到第一个最大值。
  3. 重复以上的步骤,每次比较次数-1,直到不需要比较

动画分析: 冒泡排序动画

示例:

int main() {
    const int length = 10;
    int arr[length] = {15,45,10,16,11,7,50,42,44, 11};
    bool swapped = false;

    for (int i = 0; i < length - 1; i++)
    {
        swapped = false;
        for (int j = 0; j < length - 1 - i; j++)
        {
            if (arr[j] > arr[j + 1])
            {
//                int temp = arr[j];
//                arr[j] = arr[j + 1];
//                arr[j + 1] = temp;
                swap(arr[j], arr[j+1]);
                swapped = true;
            }
        }

        cout << "第" << i + 1 << "次冒泡后:" << endl;
        for (int num: arr) {
            cout << num << " ";
        }
        cout << endl;

        if (!swapped){
            cout << "数组元素排序完成,循环提前结束" << endl;
            break;
        }
    }

    return 0;
}

5.3 二维数组

二维数组就是在一维数组上,多加一个维度。

二维数组

说明:

  1. C++对数组维度没有限制,可以从二维数组推广到三维、四维。
  2. 二维数组在内存中,按行存放。即对于int a[2][3],内存中的顺序为:a[0][0],a[0][1],a[0][2],a[1][0],a[1][1],a[1][2]

5.3.1 二维数组的定义与初始化

二维数组定义与初始化的四种方式:

  1. 仅定义

数据类型 数组名[ 行数 ][ 列数 ];

  1. 分行给二维数组初始化

数据类型 数组名[ 行数 ][ 列数 ] = { {数据1,数据2 } ,{数据3,数据4 } };

  1. 此时第一维(行数)可以省略。编辑器将根据数据中的行数推测。
  2. 赋值时,数据可以不写全,未赋值的元素将被赋0。

int a[3][4] = {{1, 2}, {3}};

  1. 逐个为数组元素赋值

数据类型 数组名[ 行数 ][ 列数 ] = { 数据1,数据2,数据3,数据4};

  1. 此时第一维(行数)可以省略。编辑器将根据数据数量除以列数的结果推测行数。
  2. 赋值时,数据可以不写全,未赋值的元素将被赋0。

int a[3][4] = {1, 2, 3};

5.3.2 二维数组应用案例

考试成绩统计:

案例描述:有三名同学(张三,李四,王五),在一次考试中的成绩分别如下表,请分别输出三名同学的总成绩

语文数学英语
张三100100100
李四9050100
王五607080

参考答案:

int main() {
	int scores[3][3] =
	{
		{100,100,100},
		{90,50,100},
		{60,70,80},
	};

	string names[3] = { "张三","李四","王五" };

	for (int i = 0; i < 3; i++)
	{
		int sum = 0;
		for (int j = 0; j < 3; j++)
		{
			sum += scores[i][j];
		}
		cout << names[i] << "同学总成绩为: " << sum << endl;
	}

	return 0;
}