目录
当我们想存储 1-10的数字时,难道需要创建10个变量来存储吗?这时候就引入的数组的概念,接下来我们来学习一下什么是数组
一.数组的概念
数组是一组相同类型元素的集合,数组中存放的是一个或者多个元素,并且多个元素的类型都是相同的,数组的元素个数不能为0。数组又分为一维数组和多维数组,多维数组中常见的一般是二维数组。
二.一维数组
1.一维数组的创建
type arr_name [常量值]
//type 表示该数组存储的是什么类型的数据
//arr_name 表示数组的名字
//[常量值] 表示数组存放的元素个数(数组的大小)
一维数组的创建:
注意:【】中必须是一个常量,不能是变量。除了在【】中直接使用常量,还可以使用宏定义的方式
#define n 5
int arr[n];
char str[n];
2.一维数组的初始化
数组的初始化是指在创建数组的时候,给数组附上一些初始值,数组的初始化一般使用大括号,将数据放在大括号中,数组的初始化分为完全初始化和不完全初始化。
//完全初始化
//数组中的元素我们都给定的对应的初始值
//这就叫做完全初始化
int arr[3]={1,2,3};
//不完全初始化
int arr[5]={1,2,3};
//我们只给部分元素设有初始值
//剩余部分默认初始化为0
//这叫做不完全初始化
数组完全初始化后存放的值:
数组不完全初始化后的值:
注意:数组初始化的值的个数不能比数组设定好的元素个数更多,否则就会报错
当给数组初始化了,那么就可以省略掉数组的大小,编译器会根据初始化的内容来自动推算数组元素的个数
3.数组的类型
int arr[10];
//在这个数组中 int是数组元素的类型
//对于数组来说,去掉数组名就是这个数组的类型
//所以arr数组的类型就是 int [10]
4.一维数组的使用
(1)数组下标:
数组其实是有下标的,下标从0开始
在C语言中对于数组的访问提供了一个操作符【】,叫做下标引用操作符,有了下标引用操作符,我们就可以轻松访问到数组中的各个元素。
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10};
printf("%d\n", arr[2]);//3
printf("%d\n", arr[6]);//7
return 0;
}
(2) 数组的输入和输出 :
对数组的元素进行输入,我们可以使用for 循环搭配scanf进行数组元素的输入,那么对数组元素进行输出,我们可以使用for 循环搭配printf进行数组元素的输出。
5.一维数组在内存中的存储
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
for (int i = 0; i < 10; i++)
{
printf("&arr[%d] = %p\n", i,&arr[i]);
}
return 0;
}
输出结果:
通过上图可以发现随着数组下标的增长,数组元素的地址也在进行递增 ,并且每次递增的大小为4个字节。那么为什么是递增4个字节呢?该数组元素的类型为int类型,int类型所占字节的大小为4个字节。由此我们可以得出一个结论:一维数组在内存中是连续存放的,并且随着下标的增长地址是由小变大存放的,每次存放的位置是由元素类型所占字节的大小进行递增的。
6.sizeof 计算数组元素的个数
sizeof 是C语言中的一个关键字,是用来计算类型和变量在内存中存放的所占字节大小,其实sizeof 也可以计算数组的大小。
int main()
{
int arr[10] = { 0 };
printf("%zd\n", sizeof(arr));//计算的是数组总大小,单位是字节
printf("%zd\n", sizeof(arr[0]));//计算的数组第一个元素的大小
//当用数组总大小除以一个元素的大小时,得出的就是数组的元素个数
printf("%zd\n", sizeof(arr)/sizeof(arr[0]));
return 0;
}
三.二维数组
1.二维数组的概念
什么是二维数组呢?二维数组就是将一维数组作为数组的元素,那么这就是二维数组。
而将二维数组作为数组元素的数组叫做三维数组,以此类推。二位数组以上的数组都统称为多维数组。
2.二维数组的创建
那么我们该如何创建二维数组呢?请看下图
type arr_name [常量值][常量值]
//第一个常量值表示该数组有几行
//第二个常量值表示该数组每一行有几个元素(几列)
//例如
int arr[3][3];
//表示创建了一个名字为 arr 元素类型为int 的 3行3列(每一行有3个元素)的二维数组
3.二维数组的初始化
二维数组的初始化与一维数组的初始化是相类似的,也是用大括号进行初始化,也分为不完全初始化和完全初始化
(1) 不完全初始化
int arr1[3][5]={1,2};
int arr2[3][5]={0};
(2)完全初始化
int main()
{
//两种完全初始化方式
int arr3[3][5] = { {1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7} };
int arr3[3][5] = { 1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7 };
return 0;
}
(3) 初始化可以省略行,不能省略列
那么二维数组的初始化为什么可以省略行,不能省略列呢?
从二维数组的概念中我们可以知道,二维数组是由多个一维数组组成的,将一维数组作为二维数组的元素,而一维数组的元素个数可以省略,同样道理,这里二位数组的行表示有几个一维数组,这里的行相当于二维数组的元素个数,所以二维数组的初始化可以将行给省略掉。
那么为什么不能省略列呢?
如果我们将列省略掉,就无法判断每一行的元素个数,既然每一行的元素个数无法判断,那我们在初始化的时候,又该如何通过每一行的元素个数来判断到底有几行呢?所以初始化的时候,行是可以省略的,列不能省略。
int main()
{
int arr5[][5] = { 1,2,3 };
int arr6[][5] = { 1,2,3,4,5,6,7};
int arr7[][5] = { {1,2},{3,4},{4,5} };
return 0;
}
4.二维数组的使用
(1)二维数组的下标
二维数组也是有下标的,二维数组的行和列的下标都是从0开始的,通过行和列的下标,我们就能快速的找到该位置的元素
int main()
{
int arr[3][5] = { {1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7} };
printf("%d ", arr[0][1]);//2
printf("%d ", arr[1][1]);//3
printf("%d ", arr[2][1]);//4
return 0;
}
(2) 二维数组的输入和输出
对二维数组的元素进行输入,我们可以使用 双重for 循环搭配scanf 进行数组元素的输入,那么对数组元素进行输出,我们可以使用 双重for 循环搭配printf 进行数组元素的输出。
int main()
{
int arr[3][5] = { 0 };
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 5; j++)
{
scanf("%d", &arr[i][j]);
}
}
printf("\n");
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 5; j++)
{
printf("%d ", arr[i][j]);
}
printf("\n");
}
return 0;
}
运行结果如下:
5.二维数组在内存中的存储
二维数组在内存中的存储会不会跟一维数组一样是连续递增的呢?我们打印出来看看
int main()
{
int arr[3][5] = { {1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7} };
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 5; j++)
{
printf("&arr[%d][%d] = %p\n", i,j,&arr[i][j]);
}
}
return 0;
}
事实上,二维数组的元素其实是这样存储的
通过上图我们也可以得出一个结论:二维数组在内存中也是连续存放的,并且随着下标的增长地址是由小变大存放的,每次存放的位置也是由元素类型所占字节的大小进行递增的。
以上就是本期的内容,希望各位小伙伴看完后能够理解数组的基本概念。