说明:本文主要对数组进行阐述,并对二维及高维数组进行举例。
数组
数组:用来存储一组同种类型数据的构造数据类型称之为数组。
- 数组属于构造类型;
- 具有相同数据类型的成员组成的一组数据;
- 存储不同类型数据的数组有对应的名称,整型数组:数组中成员变量都是整型的;浮点型数组:数组中成员变量都是浮点型的;
- 数组是由多个成员组成,每个成员被称为数组元素。
如何定义数组?
格式:类型修饰符 数组名[元素个数或常量表达式] = {值,值2,值3,…};- 类型修饰符:指定数组中元素的类型。
- [ ]中设定数组元素的个数,即数组的存储空间,只能是常量表达式,不能是变量表达式;
- 初识值之间用逗号隔开。
示例:int a[3] = {2, 3, 4};
- 数组的初始化
方式一:没有赋初始值的元素,自动设置初值为0;
示例:int b[5] = {3,4,5};//只对前三个元素赋了初始值,后两个元素自动设置为了0。
方式二:只写了数组元素个数;
示例:int c[5] = {0};//五个数组元素全部设置初值为0。
方式三:根据初始化设置,自动判断数组元素个数;
示例:int d[] = {3,4,5,6};//相当于int d[4] = {3,4,5,6};
方式四:一般写法;
示例:int e[5] = {1,2,3,4,5};
方式五:对指定的元素赋值;
示例:int f[5] = {[3] = 10,[4] = 11};//对指定下标的元素赋初值
注意:
int g['A'] = {1,4,2};//正确,相当于g[65]
int g[];//错误,编译器无法分配内存,不知道需要分配多少存储空间
int g[5];g = {1,4,2,5,4};//错误,只能在定义数组时这样进行赋值
int i = 5;
int g[i];//可以这样写,编译器会分配20个字节的存储空间,不进行初始化;
g[0] = 1;//可以这样进行正常的赋值
g[1] = 2;//但是后三个元素的值是不确定的,不会设置为0int i = 5;
int g[i] = {1,2,3,4,5};//不可以这样写,在定义数组时对数组进行初始化,元素的个数必须为常量或不写,不能是变量。
数组元素的访问
- 不能一次整体调用整个数组的全部元素的值,基本数据类型变量只存储一个数据。数据中存储多个数据,不能通过数组变量调用所有的元素。
- 访问数组元素 使用下标实现 数组名[下标]
- 下标:数组元素在数组中的序号,数组中的元素是有序的,每个元素都有序号,
序号从0开始递增,最后一个元素的序号是n-1,n表示数组元素的个数 - 下标的范围:0~n-1
- 下标可以用整型常量或变量表示
数组遍历:
- 按照顺序:从数组的第一个元素开始,访问数组的最后一个元素结束
- 使用for循环实现的数组遍历
- 循环和数组关系密切
#include <stdio.h>
int main() {
int age[5] = {18,15,33,19,25};
for (int i = 0; i < 5; i ++){
printf("age[%d] = %d\n",i,age[i]);
}
return 0;
}
5. 数组元素的修改
根据数组下标确定需要修改的数组元素。
#include <stdio.h>
int main() {
int aa[] = {1,2,3,4,5};
//遍历数组
for(int i = 0; i < 5;i ++)
{
printf("aa[%d] =%d \n",i,aa[i]);
}
printf("========\n");
// 修改数组元素
aa[1] = 22;
aa[4] = 44;
// 再遍历
for(int i = 0;i < 5;i ++)
{
printf("aa[%d] = %d \n",i,aa[i]);
}
return 0;
}
运行结果:
aa[0] =1
aa[1] =2
aa[2] =3
aa[3] =4
aa[4] =5
========
aa[0] = 1
aa[1] = 22
aa[2] = 3
aa[3] = 4
aa[4] = 44
6. 数组使用注意
- 数组越界:使用数组下标时超出数组范围,即访问了不属于数组的存储空间。编译器不会检测数组下标是否越界,因此操作数组时必须保证没有越界。
典型错误:
int Crazy[4] = {2,3,4,5};
printf("%d",Crazy[4]);//Crazy数组下标范围为0~3。
- 数组作为一个整体不能直接参与运算。
数组排序
1.常见的排序方法:冒泡排序、选择排序、插入排序等;
2.排序的规则有两种:升序、降序;
下面以冒泡排序为例说明数组排序。
冒泡排序的思路:每次将相邻的两个数进行比较,按照升序或降序进行交换,直到所有数字的顺序正确为止。
//将无序数组用冒泡排序按升序排列
#include <stdio.h>
//bubble sort
void bubbleSort(int array[], int count){
for (int i = 0; i < count - 1; i++) {
for (int j = 0; j < count - i- 1; j++) {
if (array[j] > array[j+1]) {
int temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
}
}
}
}
int main() {
// 定义数组
int array[5] = {18,15,33,19,25};
// 计算数组个数
int count = sizeof(array)/sizeof(int);
bubbleSort(array,count);
// 遍历排序后的数组
for (int i = 0; i < count; i++) {
printf("array[%d] = %d\n",i,array[i]);
}
return 0;
}
执行结果
array[0] = 15
array[1] = 18
array[2] = 19
array[3] = 25
array[4] = 33
二维数组
二维数组本质上是将数组作为数组元素的数组,称为数组的数组。为了形象化理解二维数组,通常将二维数组写成行和列的排列形式,通常被称为m行n列。
- m 二维数组中包含多少个一维数组,是第一维,表示第几行;
- n 一维数组中包含多少个元素,是第二维,表示第几列。
格式:类型修饰符 数组名[行数][列数] = {值,值2,值3,…};
1.行数可以省,列数不可以省;
int array1[][4] = {00,01,02,03,10,11,12,13,20,21,23,23,30,31,32,33};2.设置初始值时推荐使用{{},{},{}…}形式;
int array[4][4] = {{00,01,02,03},
{10,11,12,13},
{20,21,22,23},
{30,31,32,33}};3.每一行元素不足会自动补齐,补齐部分赋值为0。
二维数组遍历
- 访问单个元素必须指定两个下标,下标1代表所在的行,下标2代表所在的列;
- 与一维数组一样,也需要注意越界问题;
- 修改二维数组的元素:array[0][0] = 10;
- 二维数组遍历需要使用两层循环,第一层循环控制第几行,第二层循环控制第几列。
示例:
#include <stdio.h>
int main() {
int array[4][4] = {{00,01,02,03},
{10,11,12,13},
{20,21,22,23},
{30,31,32,33}};
for (int i = 0; i < 4; i ++){
for (int j = 0; j < 4; j ++) {
printf("array[%d][%d] = %2d ",i, j, array[i][j]);
}
printf("\n");
}
return 0;
}
运行结果:
array[0][0] = 0 array[0][1] = 1 array[0][2] = 2 array[0][3] = 3
array[1][0] = 10 array[1][1] = 11 array[1][2] = 12 array[1][3] = 13
array[2][0] = 20 array[2][1] = 21 array[2][2] = 22 array[2][3] = 23
array[3][0] = 30 array[3][1] = 31 array[3][2] = 32 array[3][3] = 33
高维数组
- 数组下标在两个以上;
- 三维数组:立体的层,行,列;
格式:类型修饰符 数组名[层数][行数][列数] = {值,值2,值3,…};
- int array[2][3][4] = {0};
说明:
- 遍历三维数组需要三层循环;
- 高维数组访问元素:数组名[下标][下标]…
- 高维数组元素个数等于各个数的乘积
- 高维数组占用内存等于元素个数乘以单个元素所占空间。
总结
1.对于类型相同的一组数据,最好选用数组进行存储;
2.下标从0开始;
3.注意越界问题;
4.数组的遍历一般采用for循环;练习
1.将一个二维数组的行和列交换,存储到另一个数组。
2.定义一个3行4列的数组,找出数组的最大元素所在行和列。答案