【C语言】数组你真的会用了吗?(关于数组的创建、初始化和使用)

一、数组的概念

数组:一组相同类型元素的集合

  • 数组的元素个数不能为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

        22 25 63 78 90

输出样例:

        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. 比较相邻的两个元素
  2. 如果第一个比第二个大,就交换他们两个
  3. 对每一对相邻的元素作上述步骤,从开始到结尾,这个时候一组数中的最大值会被放到最后一位
  4. 再除去最后一个数字,对剩下的数字继续进行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:博主水平有限,文中可能会存在错误和不足之处,望各位大佬批评指正。

  • 45
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值