朋友们,今天简简单单,继续C语言~今天要教给的对象是我们C语言的数组,因为数组的基础理解并不是很困难,所以这篇文章采用并行学习,也就是将一维数组跟二维数组同步对比推进学习。
数组的概念
数组是一组相同类型元素的集合,复杂来说:
- 数组中存放的是1个或者多个数据,但是数组元素个数不能为0。
- 数组chu的多个数据,类型是相同的。
数组的创建和初始化
一维数组的创建和初始化
创建
type arr_name[常量值];
存放在数组中的值被称为元素,数组在创建的可以指定数组的大小和数组元素的类型。
- type指定的就是数组内存放的类型,可以是char、short、float、int等。
- arr_name指的就是数组的名字,只要便于在后续编程中的理解都可以。
- 方括号中的常量值是用来指定数组大小的,也是根据实际需求来。
int math[20];//想要得到一个二十个人的数学成绩
char ch[8];
double score[22];
初始化
在创建的过程当中,我们想要给定一些初始值,这个过程就是初始化。
我们直接看例子
//完全初始化
int arr[5] = {1,2,3,4,5};
//不完全初始化
int arr2[6] = {1};//第⼀个元素初始化为1,剩余的元素默认初始化为0
//错误的初始化 - 初始化项太多
int arr3[3] = {1, 2, 3, 4};
可以看到,初始化就是在创建的语句后面补充上一个大括号,里面放上我们想要给的初始值,当然,这里给定初始值的时候就不能过分的肆意妄为了,我们在创建数组的时候已经指定了数组的大小(及方括号中的内容),那么我们在给定初始值时,初始值的个数是一定要小于等于我们指定的数组长度,上面的第三种情况就是给定的初始项过多了。而如果给定的初始化项个数小于我们指定的数组长度,那么只有你给定初始值的那几项按照你的要求完成初始化,其余的部分全部默认初始化为0。
二维数组的创建和初始化
创建
我们类比一维数组的创建,二维数组的创建也是类似
type arr_name[常量值1][常量值2];
//例如
int arr[3][18];
double real_data[2][11];
二维数组比一维数组多了一个创建的常量值,也就有了行和列的区分(一维数组只有行):
在我们的"int arr[3][18]"中
- 3表示有3行
- 18表示有每一行有18个元素,也可以理解为列
- int是表示数组当中每个元素的类型都是整型
- arr是我们自己随便定义方便理解的名字
有人可能会好奇:如果我们中括号中不输入常量值,会怎么样呢?我们先进入初始化的环节,就自然明白了。
初始化
同样的,我们类比一维数组的初始化,在创建的语句后面加上大括号,跟一维数组一样,二维数组也有完全初始化和不完全初始化,这里我们稍微详细地讲讲。
完全初始化
int arr3[3][5] = {1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7};
这里我们看到,大括号中的内容完全按照我们创建数组时规定的常量值进行初始化——一共有三组(三行),而每一行又有五个元素。加黑部分是序号,也是我们后续讲到的下标。
不完全初始化
int arr1[3][5] = {1,2};
int arr2[3][5] = {0};
arr1 | 0 | 1 | 2 | 3 | 4 |
---|---|---|---|---|---|
0 | 1 | 2 | 0 | 0 | 0 |
1 | 0 | 0 | 0 | 0 | 0 |
2 | 0 | 0 | 0 | 0 | 0 |
arr2 | 0 | 1 | 2 | 3 | 4 |
---|---|---|---|---|---|
0 | 0 | 0 | 0 | 0 | 0 |
1 | 0 | 0 | 0 | 0 | 0 |
2 | 0 | 0 | 0 | 0 | 0 |
arr1中只给定了两个数,我们就只能按照顺序初始化第一行的头两个元素,其余的默认初始化为零。
arr2中只给定了一个初始化值0,那么默认全部元素都初始化为0.
int arr5[][5] = {1,2,3};
int arr6[][5] = {1,2,3,4,5,6,7};
int arr7[][5] = {{1,2}, {3,4}, {5,6}};
//二维数组初始化时可以省略行,但是不能省略列
注意:二维数组在创建的过程中,常量值1也就是我们的行常量是可以省略的,但是列是一定不可以省略的!!!
arr5 | 0 | 1 | 2 | 3 | 4 |
---|---|---|---|---|---|
0 | 1 | 2 | 3 | 0 | 0 |
arr6 | 0 | 1 | 2 | 3 | 4 |
---|---|---|---|---|---|
0 | 1 | 2 | 3 | 4 | 5 |
1 | 6 | 7 | 0 | 0 | 0 |
arr7 | 0 | 1 | 2 | 3 | 4 |
---|---|---|---|---|---|
0 | 1 | 2 | 0 | 0 | 0 |
1 | 3 | 4 | 0 | 0 | 0 |
2 | 5 | 6 | 0 | 0 | 0 |
在创建arr7的时候我们可以看到,大括号里面还填写了三个大括号,这也就代表着这个数组有三行,而每一行我都只初始化头两个元素(因为里面的大括号内只给定了两个初始值)。这样也可以看出省略行常量后,数组初始化的灵活性,完全依靠着初始化中给定的内容进行创建。
数组的使用
一维数组的使用
数组下标
创建数组的主要目的还是为了存放数据,而对于数组,我们是规定有下标的下标是从0开始的,假设数组有n个元素,最后⼀个元素的下标是n-1,下标就相当于数组元素的编号,如下:
int arr[9]={1,2,3,4,5,6,7,8,9};
数组 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|
下标 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
在C语言中数组的访问提供了一个操作符[],这个操作符叫下标引用操作符。有了下标引用操作符,我们就可以轻松地访问到元素了。
#include <stdio.h>
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
printf("%d\n", arr[7]);//访问下标为7的数字——8
printf("%d\n", arr[3]);//访问下标为3的数字——4
return 0;
}
数组元素的打印
如果在程序当中我们想得到一个数组的全部元素,那么我们应该怎么做呢?直接看代码吧~
#include <stido.h>
int main()
{
int array[5]=[1,3,5,7,9];
int i=0;
for(i=0;i<5;i++)
{
printf("%d",array[i]);
}
return 0;
}
数组元素的输入
那如果我们想在往一个数组中放入自己想要的数据,又该如何做呢?
#include <stdio.h>
int main()
{
int array[5];
int i = 0;
for (i = 0; i < 5; i++)
{
scanf("%d", &array[i]);
}
for (i = 0; i < 5; i++)
{
printf("%d", array[i]);
}
return 0;
}
因为我们在创建数组的时候用的"int"所以我们数组里装的都是整型元素,因此不论是输出还是输入,都是用的%d。
这个难度是不是非常的一bamn呢?让我们看看看二维数组吧~
二维数组的使用
数组下标
其实二维数组访问也是使用的下标形式,而不论是行下标还是列下标,都是从0开始。
int arr[3][5] = {1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7};
例如在上面这个二维数组中,arr[2][4],表示的第三行第五列表示的就是最右边(显示)的7。
|
0 | 1 | 2 | 3 | 4 |
---|---|---|---|---|
0 | 1 | 2 | 3 | 4 |
1 | 2 | 3 | 4 | 5 |
2 | 3 | 4 | 5 | 6 |
想要输出这个元素也很简单~
#include <stdio.h>
int main()
{
int arr[3][5] = {1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7};
printf("%d\n", arr[2][4]);
return 0;
}
数组的输入和输出
类比一维数组的输入,是不是用了一个循环?那么类比过来二维数组就可以用两个循环嵌套在一起,就可以对数组中的所有元素的位置进行一次遍历啦~
#include <stdio.h>
int main()
{
int arr[3][5] = { 1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7 };
int i = 0, j = 0;
for (i = 0; i < 3; i++)//遍历行号
{
for (j = 0; j < 5; j++)//遍历列号
{
scanf("%d", &arr[i][j]);
}
}
for (i = 0; i < 3; i++)
{
for (j = 0; j < 5; j++)
{
printf("%d", arr[i][j]);
}
printf("\n");
}
return 0;
}
数组在内存中的存储
有了以上的一些基本操作,其实已经可以解决很大一部分的数组问题了,为了能深入理解数组,我们还是需要了解一下数组在内存中的存储。
一维数组在内存中的存储
我们还是从代码入手~
#include <stdio.h>
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
int i = 0;
for(i=0; i<10; i++)
{
printf("&arr[%d] = %p\n ", i, &arr[i]);
}
return 0;
}
这段代码很简单,就是依次打印数组元素的地址。
这是vs2022运行后的结果。
从输出的结果我们分析,数组随着下标的增长,地址是由小到大变化的,并且我们发现每两个相邻的元素之间相差4**(因为一个整型是4个字节)**。所以我们得出结论:数组在内存中是连续存放的。这里涉及到了一点指针的概念,我们在后续的内容当中再进行补充。
二维数组在内存中的存储
#include <stdio.h>
int main()
{
int arr[3][5] = { 0 };
int i = 0;
int j = 0;
for (i = 0; i < 3; i++)
{
for (j = 0; j < 5; j++)
{
printf("&arr[%d][%d] = %p\n", i, j, &arr[i][j]);
}
}
return 0;
}
其实类比一维数组的内存存储,还是很好理解的,这里就不再赘述了。
从输出的结果来看,每一行内部的每个元素都是相邻的,地址之间相差4个字节,跨行位置处的两个元素(如: arr[0][4]和arr[1][0])之间也是差个字节,所以二维数组中的每个元素都是连续存放的。
今天的基础数组“教给”就到这里了,希望对你有一点点点点的小帮助,后面我们会补充数组的练习以及指针内容的学习~