一、一维数组
数组是一些按序排列的同类数据元素的集合, 数组的用途可以暂时理解为用来一次定义大量变量, 例如我们要存放100个int型的整数, 如果我们一个个声明就需要定义100个int型的变量, 例如:
int a1, b1, c1, d1, e1, f1, g1, ... ;
如此, 这样是十分复杂且不符合实际的, 这时我们就需要借助一维数组来帮忙, 定义一个能够放下100个int型整数的数组:
int a[100] ;
这样就相当于完成了100个int型变量的定义, 确实很方便, 那么我们如何使用它呢? 我们可以这样认为, 定义了一个int a[100]型的数组就相当于定义了:
int a[0], a[1], a[2], a[3], ..., a[99] ;
这时只需把a[0]、a[1]他们当做一个普通的变量名即可, 例如对其中的第一个数a[0], a[1]进行赋值操作:
a[0] = 10 ; a[1] = 20 ;
代码演示:
#include<iostream>
using namespace std ;
int main()
{
int a[100] ;
a[0] = 10 ;
a[1] = 20 ;
a[99] = 30 ;
cout<< "a[0] = " << a[0] << endl ;
cout<< "a[1] = " << a[1] << endl ;
cout<< "a[99] = " << a[99] << endl ;
return 0 ;
}
输出如下:
a[0] = 10 a[1] = 20 a[99] = 30 Process returned 0 (0x0) execution time : 0.047 s Press any key to continue.
可以看出, 定义了一个 int a[100] ; 那么从 a[0] 一直到 a[99] 都可以用来当做一个普通的变量名使用, 其中 中括号 [] 之间的数称为数组的下标, 需要注意的是, 定义 a[100] 的一维数组他的下标范围是 0-99, 因为下标是从0开始的, 不是从1开始, 从0开始到99正好是一百个数, 也就是说如果定义一个大小为100的一维数组 a[100] , 那么它能够使用的下标范围是 0 - 99, 如果使用时下标不在 0-99 这个范围内就会发生不可预知的一些错误, 称为 下标越界 , 当下标越界时编译器是不会报错的, 但是运行时会发生严重的错误, 所以一定要避免下标越界这种错误的发生。
1>. 一维数组的定义:
在上面的示例中已经定义了一个int型的数组, 数组的类型不但可以是int型, 他还可以是 unsigned int型、long int型、float型、double型等基本数据类型, 也可以是以后我们将会学习的自定义的数据类型, 一旦声明了该数组的数据类型, 那么该数组中的所有元素都是声明时的数据类型, 例如:
int a[100] ; //从 a[0] - a[99] 都是int型数据 float b[100] ; //从 b[0] - b[99] 都是float型数据 double c[100] ; //从 c[0] - c[99] 都是double型数据
数组定义的一般格式:
数据类型 数组名[元素个数] ;
元素个数的一般声明方式:
①. 元素个数的定义可以直接指定一个整数值, 比如 int a[10], b[20] ; 这里的 10、20就是我们直接指定的该数组的大小(也称为长度), 还可以包含些运算符来定义数组的大小, 如:
int a[10*6] ;
这样就说明该数组的长度为60。
②. 元素个数还可以通过字符常量进行定义, 看一段代码:
#define N 10
int main()
{
int a[N] ;
return 0 ;
}
在上面的代码中我们定义了一个一维数组a, 并且指定了它的大小(长度)为10, 注意 #define N 10 这行代码, 这句的意思就表示将字符 N 定义为 常量数值10, 在下面的代码中, 出现 N 的地方就意味着将用数值10进行代替, 所以 int a[N] ;就相当于 int a[10] ;。 ③. 在介绍这种声明数组元素个数之前, 需要知道的是, 这种定义方式不适合所有的编译器, 只有支持 C99 标准的编译器才支持这种定义方式, 否则在编译时会报错, 这种声明方式就是: 使用 一个值为整数的变量 去声明一个数组的大小, 例如:
int n = 100 ; float a[n] ; //定义一个名为a, 大小为100的float型数组
2>. 一维数组的初始化:
数组的初始化是指在定义数组时, 同时对数组中的元素进行赋值的方法称为数组的初始化。
初始化举例:
int a[5] = { 1, 2, 3, 4, 5 } ;
这样就是在定义时并且对数组进行初始化了, 其中 a[0]的中的值为1, a[1]中的值为2, ... a[4]中的值为5, 我们声明了一个长度为5的数组a, 并且提供了5个初始值在大括号内, 中间用逗号隔开, 像这样的方式就是对数组的中的元素个数全部全部初始化。
还可以对一个数组中的部分元素进行初始化:
int a[5] = { 1, 2, 3 } ;
这样是只对数组的前三个元素, a[0]、a[1]、a[2]进行初始化, 没有初始化到的部分默认以0填充, 此时 a[3]、a[4]中的值就是0。
数组初始化的一般格式:
①. 形式一:
数据类型 数组名[元素个数] = { 值1, 值2, 值3, ..., 值n } ;
对于这种形式, 没有初始化到的部分将被赋上默认值0。
②. 形式二:
数据类型 数组名[] = { 值1, 值2, 值3, ..., 值n } ;
这种形式省略了数组元素个数的声明, 编译器会根据后面初始值的个数自动计算数组的长度, 例如:
int a[] = { 1, 2, 3, 4, 5 } ;
就相当于声明一个数组a, 其长度为5, 并进行初始化。可以看出, 这种初始化的方式也可以用来声明数组元素的个数。
需要注意的是, 如果不对数组进行任何初始化操作, 仅定义一个数组, 那么数组中这些元素的值是不确定的, 是系统中随机的一个值。
3>. 一维数组的使用:
数组使用时需要指定下标的值, 一维数组的一般使用形式:
数组名[下标]
例如:
int a[10] = {} ; //定义并全部初始化为0 int i = 3 ; //定义一个普通整形变量, 初始值为3 a[1] = 10 ; //将数组a[1]赋值为10 a[1+1] = 20 ; //将数组a[2]赋值为20 a[i] = 30 ; //将数组a[3]赋值为30
下标必须是一个整数, 可以是常量、变量、表达式, 例如 a[1]、a[i]、a[i+1]这样的使用都是合法的。
由于编译器不做下标的越界检查, 所以必须要注意下标的越界问题, 避免下标越界这样的错误发生。
4>. 一维数组使用举例:
输入5个数并逆序输出
输入: 15 13 11 8 26
输出: 26 8 11 13 15
输入时每个数中间用空格隔开。
代码:
#include<iostream>
using namespace std ;
int main()
{
int a[5] ; //定义一个元素个数为5的数组
int i ; //用于控制for循环
cout<< "Please input 5 numbers:" ; //提示输入5个数
for( i = 0; i < 5; i++ ) //输入
cin >> a[i] ;
for( i = 4; i >=0; i-- ) //控制下标从4到0逆序输出
cout << a[i] <<" " ;
return 0 ;
}
二、进一步理解
1>. 数组在内存中所占的空间大小
我们已经知道, 一个int型元素所占的内存为4字节(以较新的GCC编译器为例), 那么如果定义一个 int a[10] ;这样的数组在内存中将会占用多大的内存呢?
可以实际测量一下, 使用sizeof运算符,
#include<iostream>
using namespace std ;
int main()
{
int a[10] ;
cout<<sizeof(a)<<endl ;
return 0 ;
}
输出的结果为40, 也就代表是40个字节, 一个int型为4个字节, 数组的大小是10, 4 * 10正好是40, 如果不确定还可以从a[0]到a[9]一个个测量其占用的存储单元大小, 然后相加, 这里就不再贴出代码了。
总结下就是:
数组所占的内存单元大小 = 数组数据类型的大小 * 元素个数
例如 double b[10] ;所占的内存大小就是 一个double型数据大小8 * 元素个数 10, 即80个字节。
2>. 一维数组在内存中的存放状态
一维数组在内存中实际上是一段连续的内存单元, 当定义好一个数组时, 一段连续的内存单元就被开辟出来用于存放数组中元素的值, 假如我们定义一个数组int a[10], 那么它在内存中的情况可以想象成如图所示的状态:
数组中的每个元素实际上都有一个自己的地址, 这些元素所对应的地址实际上全部都是为了方便表示而假设的, 数组在真实的运行中所使用的地址是根据当前系统的内存状态而定, 所以说即时运行同一个程序, 每次运行时数组所使用的内存单元地址也极有可能不同。
从图中还可以看到一点, 从a[0]到a[9]的内存地址不是 1000、1001、1002... 这样连续的方式进行排列的, 而是 1000、1004、1008...这样每隔4个数出现一个, 这样的原因是因为一个int型是4个字节, 而一个存储单元的大小为一字节, 所以一个int型数据就需要4个存储单元, 也就是4个字节, 这里用一个方格表示一个元素是为了能够直观的进行表示。
在内存中的存放状态这块, 目前我们只需先对其有个相关的印象即可, 更详细的介绍将会在以后将会学习的指针中进行。