一、数组的概念
数组:一组相同类型元素的集合
- 数组的元素个数不能为0
- 同一个数组内的元素类型是相同的
数组分为一维数组和多维数组,多维数组中二维数组最为常见,所以本文主要介绍一维数组和二维数组的使用
二、一维数组
1. 一维数组的创建
类型说明符 数组名 [常量表达式]
- 类型说明符 指定数组的元素类型,可以为 int、double、char等,也可以为自定义的类型
- [常量表达式] 指定数组的大小,即数组中所包含的元素个数,一般根据实际需求设置,表达式可为常量或符号常量,但一定不能为变量( 如:int arr[x])
- 数组名 可以为数组命名
例如,我想创建一个放200个int类型的元素的数组,名字为arr,就可以这样写
int arr[200];
也可以创建其他类型的数组:
char str[5];
double maximum [10];
2. 一维数组的初始化
定义数组时给数组赋值,称为数组的初始化。
初始化有下面几种情况:
(1)全部初始化
int arr[4] = {0,1,2,3,};//{}中的元素个数不可以超过[]中的常量值
(2)部分元素赋初值
int brr[10] = {0,1,2,3,4};//前五个元素依次赋值,其他未赋值元素默认为0
(3)全部元素赋0
int crr[3] = {0,0,0};
也可以写成:
int crr[3] = {0};
(4)对所有数组元素赋初值时,可以不指定数组长度
int arr[] = {0,1,2,3,4};//这个数组的长度为{}中元素的个数,即arr数组的大小为5
3.一维数组的使用
数组定义好后就可以使用它了,但不能一次性引用整个数组,只能引用单个数组元素。这个时候我们为了方便访问和操作数组中的元素,于是就有了数组的下标。
3.1 数组的下标
引用数组元素的形式为:
数组名[下标]
- 下标的意义:数组下标是一个整数,用于访问数组中的特定元素。通过下标,我们可以直接访问、读取或修改数组中的元素。
- 下标的范围:数组下标的取值范围是从0到n-1,其中n是数组的长度。这意味着在C语言中,数组的最大下标是元素个数减1。
- 下标的连续性:由于数组在内存中是连续存储的,所以数组下标也是连续的。这允许我们通过循环等方式遍历整个数组,并对每个元素进行处理。
有了数组的下标,如果我有一个长度为N的数组,我想访问下标为2的元素,我就可以使用arr[1],只要想访问下标为a(a为任意小于N的常数),我就可以使用arr[a-1]。
#include <stdio.h>
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,0 };
printf("%d\n", arr[0]);//输出1
printf("%d\n", arr[6]);//输出7
return 0;
}
运行结果
3.2 打印数组的元素
现在我们已经知道了如何访问数组中单个元素了,那我们如果想要访问整个数组的内容,那怎么办呢?
其实,我们只需要把数组从第一个元素访问到最后一个,不就是访问整个数组了吗,那我们应该怎么访问呢?最常用的方法就是使用for循环(while循环也可以),产生从0到n-1的下标,如何使用下标进行访问就可以了。
#include <stdio.h>
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,0 };
int i = 0;
for (; i < 10; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
运行结果:
3.3 数组的输入
如果我们定义了一个数组之后,我们该如何给数组输⼊想要的数据呢?
在C语言中,给数组输入数据通常是通过循环结构来实现的,如for循环或while循环。
#include <stdio.h>
int main() {
int arr[5];
printf("请输入5个数字:\n");
for(int i = 0; i < 5; i++) {
scanf("%d", &arr[i]);
}
return 0;
}
4. 一维数组的应用
讲了太多的知识点,现在给出几个例子,来让我们更加深刻地体会一维数组如果使用吧。
【例1】输入20个整数,然后逆序将这20个数打印出来
对于这个例子,我们可以定义一个长度为20的数组arr来存放输入的20个数,然后再将数组arr中的内容逆序输出即可。
#include <stdio.h>
int main()
{
int arr[20];
int i = 0;
for (; i < 20; i++)
{
scanf("%d", &arr[i]);
}
for (i = 19; i >= 0; i--)
{
printf("%d ", arr[i]);
}
return 0;
}
输出结果:
【例2】输出n个数(n <= 1000),存放在数组arr[1] 到 arr[n] 中,输出最大数以及其所在的位置
输入样例:
5
输出样例:
90 5
#include <stdio.h>
int main()
{
int arr[1001] ;//n<=1000,所以数组最大长度为1001
int i = 0, n;
scanf("%d", &n);//输入数组的实际大小
for (i = 1; i <= n; i++)
{
scanf("%d", &arr[i]);
}
int max = arr[1],m = 1;//为最大值和对应位置赋初始值
for (i = 2; i <= n; i++)
{
if (max < arr[i])
{
max = arr[i];
m = i;
}
}
printf("%d %d", max, m);//输出
return 0;
}
这个例子看完之后,可以再想想如何从一组数据找到最小值及其所在位置?我们可以试着写一写,由于思路写法与上面类似,这里我就不给出代码了。
【例3】将输入的10个数自动从小到大排序然后输出
这个例子我们可以使用冒泡排序(Bubble Sort)来解决
冒泡排序的算法:
- 比较相邻的两个元素
- 如果第一个比第二个大,就交换他们两个
- 对每一对相邻的元素作上述步骤,从开始到结尾,这个时候一组数中的最大值会被放到最后一位
- 再除去最后一个数字,对剩下的数字继续进行1-3的步骤,然后再持续这个过程,大的数字就会被一个一个顶到后面去,直到只剩下最后一对数字也不需要交换时,这组数字就这样被排好了
冒泡排序的名字来源于其工作方式,就像碳酸饮料中的气泡最终会上浮到顶端一样,较大的元素会慢慢“浮”到数列的后面,完成排序。
冒泡排序是一种稳定排序算法,因为它在排序过程中保持相同元素的相对顺序不变。它的时间复杂度是O(n²),这意味着对于含有n个元素的序列,最多需要进行n(n-1)/2次比较操作。
冒泡排序的一个关键特征是,它重复地遍历要排序的元素列表,比较每对相邻的元素,并交换它们(如果需要),直到没有更多的交换需要执行。这通常通过两个嵌套循环实现,外循环控制遍历次数,内循环负责执行实际的比较和交换操作。
好了,弄清楚了冒泡排序,现在让我们来写这段代码吧
#include <stdio.h>
int main()
{
int arr[10];
int i = 0;
for (; i < 10; i++)
{
scanf("%d", &arr[i]);
}
for (i = 0; i < 9; i++)
{
int j = 0;
for (j = 0;j < (9 - i); j++)
{
int t = 0;
if (arr[j] > arr[j + 1])
{
t = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = t;
}
}
}
for (i = 0; i < 10; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
运行结果:
好了,如果你看到了这里,上面三个例子是否让你知道一维数组怎么使用了呢?
现在,我再给出一个例子,你可以试试着写一写,代码我会在本文的最后再给出,好了,来试试看吧!
【例4】从键盘输入若干整数(数据个数应少于50),其值在0-4的范围,用-1作为输入结束的标志。统计每个整数的个数。
三、二维数组
1.二维数组的创建
二维数组其实就是具有两个下标的数组,它是一种特殊的一维数组,其每个元素都是一个一维数组。二维数组也可以被看作是一个表,其有行和列。
二维数组我们可以这样来定义:
类型说明符 数组名[常量表达式1] [常量表达式2]
- 常量表达式1 :行的长度
- 常量表达式2 :列的长度
- 二维数组的大小 = 常量表达式1 * 常量表达式2 (元素总个数等于行数x列数)
int arr[3][3];//定义一个3行3列的二维整型数组,元素个数为3*3=9
char str[7][6];//定义一个7行6列的二维字符型数组,元素个数为7*6=42
既然我说有两个下标的的数组就是二维数组,那么拥有多个下标的数组不就是多维数组了吗,又根据上面一维数组和二维数组定义的相似,我们不难想出三维数组、四维数组的建立。
int [1][2][3];
int [1][2][3][4];
多维数组的引用赋值等操作与二维数组类似,但三维以上的数组很少用,因为这些数组需要占用大量的存储空间。
2. 二维数组的初始化
二维数组的初始化可以有下面几种操作:
(1)分行初始化
int arr[2][3] = { {0,1,2},{3,4,5} };//第一行为{0,1,2},第二行为{3,4,5}
前面也说了,二维数组的元素就是一维数组,所以就可以像这样,以一维数组为元素用{ }括起来,这个几行也可以看成几个元素(即几个一维数组),几列可以看成表示的是这个一维数组的大小
(2)按行顺序一次性初始化
int arr[2][3] = { 0,1,2,3,4,5 };//这个数组与上面的数组是相等的
(3)部分初始化(不完全初始化,即只给数组中的部分元素赋初始值)
int arr[2][3] = { {1},{2,3} }; //相当于: int arr[2][3] = { {1,0,0},{2,3,0} };
因为之前一维数组的初始化我们知道:未赋值的元素系统默认为0,而一维数组赋值会从前开始依次赋值。
(4)省略行下标的初始化
对二维数组初始化时,行标可以省略,但列标一定不能省略!
int arr[][3] = { 0,1,2,3,4,5 };//这是一个2行3列的数组 //相当于: int arr[2][3] = { 0,1,2,3,4,5 }; int brr[][3] = {{0},{1,2},{3,4,5}} ;//这是一个3行3列的数组 //相当于: int brr[3][3] = {{0},{1,2},{3,4,5}} ;
3. 二维数组的使用
二维数组元素访问的一般形式:
数组名[行下标][列下标]
这个其实我感觉与一维数组的使用也是类似的,二维数组的行标和列标都是从0开始的,如果我们定义时行下标有N个,那么行下标取值范围就是1~N-1,列下标类似。
二维数组中各个数组元素在内存中的存储顺序是“按行优先原则顺序存放”,就是先从第一行第一个开始存放,第一行存放完,再从第二行开始第一个开始,直到最后一个最后一行。而且⼆维数组中的每个元素都是连续存放的。
数组元素可以与变量一样,能进行各种运算
#include <stdio.h>
int main()
{
int arr[2][3] = { 1,2,3,4,5,6 };
arr[0][2] = 9;
arr[0][0] = 11;
arr[1][2] = arr[1][0] + arr[0][1];
int i, j;
for (i = 0; i < 2; i++)//输出每一行
{
for (j = 0; j < 3; j++)//输出每行的每个元素
{
printf("%d ", arr[i][j]);
}
}
return 0;
}
运行结果:
4. 二维数组的应用
【例5】矩阵的转置,在键盘上输入一个4*3的矩阵,将其转换成3*4的矩阵输出
输入样例: 输出样例:
1 2 3 1 4 7 0
4 5 6 2 5 8 1
7 8 9 3 6 9 2
0 1 2
#include <stdio.h>
int main()
{
int arr[4][3];
int i, j;
for (i = 0; i < 4; i++)//输入矩阵
{
for (j = 0; j < 3; j++)
{
scanf("%d", &arr[i][j]);
}
}
printf("\n");
for (i = 0; i < 3; i++)//输出矩阵
{
for (j = 0; j < 4; j++)
{
printf("%d ", arr[j][i]);
}
printf("\n");
}
return 0;
}
运行结果:
【例6】求矩阵的对角线之和,键盘先输入N(其中N <= 100),再输入一个N*N矩阵,然后输出矩阵正对角线和负对角线之和。
#include <stdio.h>
int main()
{
int arr[100][100];
int N;
scanf("%d", &N);
int i, j;
for (i = 0; i < N; i++)
{
for (j = 0; j < N; j++)
{
scanf("%d", &arr[i][j]);
}
}
int a = 0, b = 0;
for (i = 0; i < N; i++)
{
a += arr[i][i];//正对角线从第一行第一个开始,以后每个元素都在前一个基础是行列数+1
b += arr[i][N - 1 - i];//负对角线从第一行最后一个开始,以后每个元素都在前一个
} //基础上行+1,列-1
printf("%d %d", a, b);
return 0;
}
运行结果:
【例4】
#include <stdio.h>
int main()
{
int arr[50];
int i,a=0,b=0,c=0,d=0;
for (i = 0; i < 50; i++)
{
scanf("%d", &arr[i]);
switch (arr[i])
{
case 1:a++; break;
case 2:b++; break;
case 3:c++; break;
case 4:d++; break;
}
if (arr[i] == -1)
break;
}
printf("1的个数:%d\n2的个数:%d\n3的个数:%d\n4的个数:%d\n", a, b, c, d);
return 0;
}
运行结果:
好了,到这里全文就结束啦~
ps:博主水平有限,文中可能会存在错误和不足之处,望各位大佬批评指正。