数组的作用
它可以分配大量的内存,也可以保证数据类型的一致性,关键可简化代码的书写
数组的特点
1)是一种内存分配的方法
2)保证分配内存中的数据类型的一致性
3)可以分配大量内存
4)分配得到内存是连续的
定义数组的语法格式
数据元素类型 数组名[数组长度 (数组元素个数) ] = {初始值,初始值之间使用,间隔};
例如:int a[5] = {1,2,3,4,5};
语义:连续分配5个元素内存空间,每个元素的数据类型都是int类型
每个元素占据4字节内存空间
最终连续分配了20个字节的内存空间
5个元素对应的内存空间中存储的值分别为1,2,3,4,5
相当于 int a0 = 1,a1 = 2,a2 = 3, a3 = 4, a4 = 5;
使用数组时注意事项
1)数组分配的内存是连续
2)数组下标就是数组中元素的编号(索引导 index)数组下标从0开始
int a[5] = {1,2,3,4,5};
数组元素 下标 叫法 表示方式
1 0 数组中第0个元素 a[0]
2 1 数组中第1个元素 a[1]
… … … …
5 4 数组中第4个元素 a[4]
3)数组元素的访问方式
使用了[]元素符,语法格式:数组名[下标]
读数组中某个元素的值 数组名[下标]
向数组中某个位置写入值 数组名[下标] = 写入的值
例如:int a[5] = {1,2,3,4,5};
int m = a[0]; //读操作 m=1
printf(“a[3]=%d\n”, a[3]);
a[4] = 100; //5---->100 写操作
特别注意:数组的越界访问问题
数组越界访问,给定的下标值 超出了[0,数组元素个数-1]
int a[5] = {1,2,3,4,5};
a数组中一共有5个元素,其下标为 0 1 2 3 4
a[5] = 100; //属于数组越界访问
a[-1] = 22; //属于数组越界访问
printf("a[5]=%d\n", a[5]); //属于数组越界访问
数组越界访问,会造成严重的后果,往往程序崩溃
4)数组长度又称数组元素个数,不是数组占据的内存大小
例如:int a[5];
数组长度式5 也就是说数组元素个数式5
该数组占据的20个字节内存空间
数组定义的形式
1)int a[5] = {1,2,3,4,5};
2) int a[5] = {1,2,3}; //a[0] = 1 a[1] = 2 a[2] = 3 其余元素都是0 a[3] = 0 a[4] = 0
3)int a[5] = {0};//初始化为全0
4)int a[5] = {};//初始化为全0
5)int a[5];//只定义 分配20个字节内存空间 不做初始化,其对应内存中的存储的内容不可预知
6)int a[] = {1,2,3}; //编译器自动推导出数组长度(元素个数)为3个,并初始化为1,2,3
7) int a[5] = {1,2,3,4,5,7,8};//编译器会分配5个元素 初始化为1,2,3,4,5 忽略掉7 8
比较常见的错误形式:
int a[]; //编译立马报错
求数组元素个数的公式
数组名,它一个常量 代表整个数组的首地址 也就是数组中第0个元素的地址
整个数组占据的内存空间大小 = sizeof(数组名)
第0个元素占据的内存空间大小 = sizeof(a[0])
数组元素个数 = sizeof(数组名) / sizeof(数组第0个元素);
//数组名,它一个常量 代表整个数组的首地址 也就是数组中第0个元素的地址
a = &a[0]; //数组中第0个元素的地址
&a[1]; //数组中第1个元素的地址
注意:数组元素个数是在定义数组变量时确定下来的,后续是不能改变数组大小
int a[]={1,2,3}; //数组元素个数为3
a ={1,2,3,4,5}; //数组越界访问
多维数组
int a[10];//一维数组 (重点)
int a[3][4];//二维数组 (重点)
int a[2][3][4];//三维数组
二维数组的基本概念
二维数组中的每个元素是一个一维数组
而一维数组又包含若干数据项
所以二维数组是由一维数组组成的 本质上来说就是一个一维数组
语法格式
数据元素类型 二维数组名[二维数组长度][一维数组长度] = {初始化列表};
例如:
int a[5][3]={{1,2,3}, {4,5,6}, {7,8,9}, {10,11,12}, {13,14,15}};
语义:
1)a代表二维数组, 包含5个元素 每个元素是一个一位数组
每个一位数中又包含3个数字(元素)
俗称就是5行3列的二维数组
a是这个二维数组的名称 ,也是这个二维数组的首地址
2)a[0]代表 a二维数组的第0个元素,也就是一个一维数组
a[0]就是第0个元素的首地址
a[1] 第1个元素的首地址
..
a[4] 第4个元素的首地址
二维数组元素的读写方式
a[0][0] 代表的是二维数组第0个元素的第0个数字
int num = a[0][0];//读
a[1][2] = num;//写
二维数组的定义形式
1) int a[5][3]; //只定义不做初始化 对应内存中的数据不可预知
2) int a[5][3]={{1,2,3}, {4,5,6}, {7,8,9}, {10,11,12}, {13,14,15}};
3) int a[5][3]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};//编译器自动拆分等价于 2)
4) int a[5][3]={0}; //初始化为全0
5) int a[][3] ={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};//编译器自动解析为a[5][3]类型
二维数组的终极公式
int a[2][3] = {0};
1) a是二维数组的首地址=第0个行的地址(a[0])=第0行第0列元素的首地址(&a[0][0])
2) sizeof(a):整个二维数组占据的内存空间大小 sizeof(int)23= 24Byte
3) sizeof(a[0]):二维数组中第0行占据的内存空间大小 sizeof(int) * 3 = 12
4) sizeof(a[0][0]): 二维数组中第0行第0列占据的内存空间大小 sizeof(int) = 4;
5) sizeof(a)/sizeof(a[0]): 数组总长度/第0行的长度, 二维数组长度 24/12 = 2
6) sizeof(a[0])/sizeof(a[0][0]): 一维长度数组长度 12/4 = 3
7) sizeof(a)/sizeof(a[0][0]): 所有元素个数 24/4 = 6
注意事项
1)二维数组定义占据空间大小即确定
int a[3][8] ={0}; //大小确定384 字节
2)二维数组访问时也不能越界访问 否则很容易引起程序崩溃
a[4][0] = 100;
a[-2][0] = 11; 都属于越界