1. 数组
1.1 数组的定义
- 数组:是一种复合数据类型,是具有相同名称和类型的变量的有序集合。
- 数组:在内存中,它占据一组连续的内存位置。为了引用数组中的特定位置或元素,我们制定了数组名称和数组中特定元素的位置编号。
1.2 数组元素及数组下标越界
- 数组元素:数组中的变量(即数组的每一项)称为一个元素,每个元素的存取都是通过数组名加偏移来实现的,数组元素从0开始,数组下标范围为:0~n-1(n个元素)。
数组越界:就是当访问超出了数组的下标的范围0~n-1(数组一共包含n个元素),会引发系统崩溃,要相当注意。
(1)查看数组下标程序示例:#include<iostream> using namespace std; int main() { int a[5] = {0,1,2,3,4}; for(int i=0; i<5; i++) { cout<<"a["<<i<<"] = "<<a[i]<<endl; } system("pause"); return 0; } =>a[0] = 0 a[1] = 1 a[2] = 2 a[3] = 3 a[4] = 4
(2)数组下标越界程序示例:
#include<iostream> using namespace std; int main() { int a[5]; int i; for(i=0; i<=5; i++) { a[i] = i; } for(i=0; i<=5; i++) { cout<<"a["<<i<<"] = "<<a[i]<<endl; } system("pause"); return 0; } =>数组越界,编译程序不会报错误。 a[0] = 0 a[1] = 1 a[2] = 2 a[3] = 3 a[4] = 4 a[5] = 5 运行结束奔溃,报错提示:Run-Time Check Failure #2 - Stack around the variable 'a' was corrupted.
1.3 一维数组在内存中的分布
一维数组在内存中的分布列表:
值 变量 变量 变量 变量 …… 变量 数组下标 a[0] a[1] a[2] a[3] …… a[n] 注:数组元素就像排列好队的士兵,他们在内存中也都是按照编号顺序排放的。
1.4 定义数组
- 数组定义的格式为:类型名 数组标识符[常量表达式];
数组定义:是具有编译确定意义的操作,它分配固定大小的空间,就像变量定义一样的明确,因此元素个数必须是由编译时就能够定夺的常量表达式;
#include<iostream> using namespace std; int main() { //int n=5;//错误定义,数组的下标定义必须是常量 const int n=5;//将数组的下标定义为常量 int a[n]; int i; for(i=0; i<n; i++) { a[i] = i; } for(i=0; i<n; i++) { cout<<"a["<<i<<"] = "<<a[i]<<endl; } system("pause"); return 0; } =>a[0] = 0 a[1] = 1 a[2] = 2 a[3] = 3 a[4] = 4
注:
如:int n=100; int a[n]; //错,数组元素个数必须是常量
数组的下标只能定义为常量:const int n=100; int a[n]; //对,n是常量
1.5 数组的初始化
- 方式一:显式指定数组长度为n,依次全赋值初始化,假设数组长度为n,就依此初始化n个元素。
int a[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9} ; - 方式二:显式指定数组长度为n,只赋值一部分,剩下的赋值为0,假设数组长度为n,就依此初始化前x个元素,剩下的n-x个元素赋值0。
int a[10] = {0, 1, 2, 3, 4} ; - 方式三:显式指定数组长度为n,全部依次全赋值初始化为0,假设数组长度为n,就依此初始化n个元素赋值为0。
int a[10] = {0}; - 方式四:不指定数组长度,依次全赋值初始化,假设数组长度为n,就依此初始化n个元素。
int a[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9} ;
1.6 数组名的含义
在C++中声明数组时,系统会自动生成一个指向该数组的指针 ,而该指针通常指向数组第1个元素的内存地址。
声明数组a: int a[4]; 系统自动生成的指针为:int* a = &a[0];
代码示例一:
#include <iostream> using namespace std; int main() { int a[5]={0, 1, 2, 3, 4}; cout<<a<<endl; cout<<&a<<endl; cout<<a+1<<endl; cout<<&a+1<<endl; return 0; } =>0012FF6C 0012FF6C 0012FF70 0012FF80
解析:
—a是数组名,代表数组第一个元素地址即首地址和&a[0]是一个意思,a+1是数组第二个元素的地址,如此类推。
—&a也是数组的首地址,但是意义跟a完全不一样,它是表示取整个数组的地址,&a+1代表示一次移动一个数组长度,如此类推。代码示例二:
#include <iostream> using namespace std; int main() { int a[5]={1, 25, 50, 75, 100}; int *ptr1=(int*)(&a+1); int *ptr2=(int*)((int)a+1); cout<<ptr1[-1]<<"\t"<<*ptr2<<endl; return 0; } =>100 33554432
解析:
—&a+1是数组最后元素的下一个地址,所以ptr1保存的是最后一个元素的下一个地址,ptr1[-1]相当于*(ptr-1)即取数组最后一个元素的地址对应内存里的数据值。
—(int)a+1,因为强制转换运算符高于算术运算符,所以相当于((int)a)+1;(int)a就是将数组的第一个元素的地址转换为整数类型。
1.7 枚举常量与数组
- 用枚举常量来代替枯燥的数字变量,能让程序员很形象地理解该变量做什么用的,便于调试。
enum num{one, two, three, four, five, six, seven, eight, nine, ten} ;
枚举默认初始化为0,1,2,3,4,5,6,7,8,9
num figer[ ] = {one, two, three, four, five};
figer则是一个含有num类型5个元素的数组。
参考文献
[1]《C++全方位学习》范磊——第十四章
[2]《C++程序设计教程(第二版)》钱能——第三章
[3]《C++Primer(中文版)》王刚、杨巨峰——第三章
[4] 百度搜索关键字:C++数组、一维数组、数组元素、数组下标、数组下标越界、数组名、一维数组在内存中的分布