C++数组的定义和使用(入门必读)
很多场景中,需要把多个类型相同的数据放在一块儿处理,比如一个班级中所有学员的数学成绩、一串字符等。为了方便存储和处理这些类型相同的数据,C++ 提供了数组。
我们知道,要想把数据放入内存,必须先要分配内存空间。放入 4 个整数,就得分配 4 个 int 类型的内存空间:
我们把这样的一组数据的集合称为数组(Array)。
数组中的各个元素,也就是每个数据,都没有单独的名字,要访问其中的某一个数据,需要使用数组名和下标。数组名就是这个数组的标识符,而下标就是某个数据在数组中的序号,该序号从 0 开始。
访问数组元素时,数组名后面跟一对中括号,下标写在中括号里面,其语法如下:
数组有两个属性,分别是类型和长度。数组的类型就是元素的类型,数组的长度就是这个数组中元素的最大个数。例如一个存储 10 个整数的数组,其类型就是整型,而长度就是 10。
具体来讲,数组占用的是一块连续的内存空间,它的大小等于各个元素所占内存大小的总和。由于各个元素的类型相同,所以数组占用的内存大小就等于数组的长度与一个元素所占内存大小的乘积。
例如:
初始化数组有以下几种方式:
注意,初始化数组指的是定义数组的同时为各个元素提供初值。对于先前定义的数组,不能采用初始化的方式指定各个元素的值,例如:
举个简单的例子:
在 C++语言中,编译器并不会对数组下标的有效性做出检测,超出数组下标范围的操作会导致不可预料的后果。因此,程序员必须自己保证数组下标的有效性。
例如:
实际场景中,经常借助循环结构修改数组元素的值。例如:
某些场景需要让两个数组中各个元素的值相同,初学者经常犯的错误就是直接用数组名相互赋值:
同样的道理,使用 cin 和 cout 输入与输出数组元素的时候,也只能单独对每个元素进行操作,而不能直接对数组进行操作。
我们知道,要想把数据放入内存,必须先要分配内存空间。放入 4 个整数,就得分配 4 个 int 类型的内存空间:
int a[4];这样,就在内存中分配了 4 个 int 类型的内存空间,共 4×4=16 个字节,并为它们起了一个名字,叫 a。
我们把这样的一组数据的集合称为数组(Array)。
数组中的各个元素,也就是每个数据,都没有单独的名字,要访问其中的某一个数据,需要使用数组名和下标。数组名就是这个数组的标识符,而下标就是某个数据在数组中的序号,该序号从 0 开始。
访问数组元素时,数组名后面跟一对中括号,下标写在中括号里面,其语法如下:
数组名[下标];假设某个数组 a 有 10 个元素,则访问第一个、第三个和第十个元素可分别写为 a[0], a[2] 和 a[9]。
数组有两个属性,分别是类型和长度。数组的类型就是元素的类型,数组的长度就是这个数组中元素的最大个数。例如一个存储 10 个整数的数组,其类型就是整型,而长度就是 10。
除了类型相同以外,数组中的数据还有一个特点,就是数组中的各个元素在内存中是按照顺序依次排列存储的。由于数组的下标是从 0 开始,所以一个长度为 10 的数组,它的下标区间是 [0, 9]。
具体来讲,数组占用的是一块连续的内存空间,它的大小等于各个元素所占内存大小的总和。由于各个元素的类型相同,所以数组占用的内存大小就等于数组的长度与一个元素所占内存大小的乘积。
数组的定义
使用数组之前必须先定义数组。定义数组的语法如下:类型 数组名[数组大小];
- 数组类型就是数组中各元素的数据类型;
- 数组名是这个数组的标识符,用来唯一标识数组,命名必须符合标识符的命名规范;
- 数组的长度由一个常量表达式指定,可以是整型字面常量、枚举常量或者用 const 修饰的常量。
例如:
int num[10]; //正确 int length = 10; char str[length]; //错误,length 是变量 const int length2 = 10; char str[length2]; //正确 char arr[10 + 1]; // 正确 char arr2[length2 + 1]; // 正确与变量的定义一样,数组也可以连续定义。例如:
int a[10], b[20], c[30];
数组的初始化
定义数组的同时,为数组中的元素提供初值,这就是所谓的初始化数组。初始化数组有以下几种方式:
1) 全部初始化
为数组中的所有元素提供初值,例如:int num[5] = {10, 20, 30, 40, 50};
2) 部分初始化
只提供一部分元素的初始值,其他元素将自动初始化为零。例如:int num[5] = {10, 20}; // 其余元素初始化为 0在 num 数组中,num[0] 的值是 10,num[1] 的值是 20,后续 3 个元素的值都是 0。
3) 自动推断数组大小
初始化数组时,可以省略数组的大小,编译器可以自动推断出数组的大小。例如:int num[] = {10, 20, 30, 40, 50}; // 编译器自动推断大小为 5
注意,初始化数组指的是定义数组的同时为各个元素提供初值。对于先前定义的数组,不能采用初始化的方式指定各个元素的值,例如:
int num[5]; num = {10, 20, 30, 40, 50}; // 错误,不能这样赋值这样写是错误的,对于先前定义的数组,只能分别为各个元素赋值。
数组的使用
数组的使用主要涉及访问和修改数组中的元素。1) 访问数组元素
访问数组元素的基本方法是用“数组名[下标]”的形式,数组的下标可以是常量,也可以是变量或者含有变量的表达式。举个简单的例子:
#include <iostream> int main() { int num[5] = { 10, 20, 30, 40, 50 }; int a = num[0]; //访问数组中的第一个元素,并赋值给变量 a std::cout << a << std::endl; return 0; }输出结果为:
20
注意,使用下标访问数组元素时,不能超出数组下标的取值范围。例如上面程序中,数组 num 下标的取值范围是 [0, 4],不能取范围之外的值。在 C++语言中,编译器并不会对数组下标的有效性做出检测,超出数组下标范围的操作会导致不可预料的后果。因此,程序员必须自己保证数组下标的有效性。
2) 修改数组元素
在定义数组之后,不可以直接对数组进行赋值。要想修改其中元素的值,只能通过下标的方法先找到要操作的元素,然后进行处理。例如:
#include <iostream> int main() { int num[5] = { 10, 20, 30, 40, 50 }; std::cout <<"修改前:"<< num[2] << std::endl; num[2] = 100; // 修改数组中第 3 个元素的值。 std::cout << "修改后:" << num[2] << std::endl; return 0; }输出结果为:
修改前:30
修改后:100
实际场景中,经常借助循环结构修改数组元素的值。例如:
#include <iostream> int main() { int num[5] = { 10, 20, 30, 40, 50 }; for (int i = 0; i < 5; i++) { num[i] = i; //用循环修改数组中元素的值 } //输出数组中各个元素的值 for (int i = 0; i < 5; i++) { std::cout << num[i] << " "; } return 0; }输出结果为:
0 1 2 3 4
某些场景需要让两个数组中各个元素的值相同,初学者经常犯的错误就是直接用数组名相互赋值:
int a[5]={1,2,3,4,5}; int b[5]; b = a; // 错误,不能这样赋值上面的赋值语句是错误的,正确的做法是借助循环结构将数组中的各个元素分别赋值:
for (int i = 0; i < 5; i++) { b[i] = a[i]; }
同样的道理,使用 cin 和 cout 输入与输出数组元素的时候,也只能单独对每个元素进行操作,而不能直接对数组进行操作。
#include <iostream> int main() { int num[5]; //std::cin >> num; for (int i = 0; i < 5; i++) { std::cin >> num[i]; } //std::cout << num; for (int i = 0; i < 5; i++) { std::cout << num[i] << " "; } return 0; }其中,注释部分为错误的写法。
总结
数组就是一组数据的集合,程序中使用数组的时候需要注意以下几点:- 同一数组中的所有元素必须是同一类型,尝试存储不同类型的元素会导致编译错误。
- 数组的长度在定义的时候必须确定,不能为变量。
- 定义后的数组,大小就不能改变了,所以在编程时,必须确保数组的大小符合需求。
- 操作数组中的元素,不能超出数组下标的范围。