C语言基础之——数组

前言:本篇文章,我们将对一维数组,和二维数组进行展开式的讲解,并进行实际应用。

目录

一.一维数组

1.一维数组的创建和初始化

(1)数组的创建

(2)数组的初始化

2.一维数组的使用

3.一维数组在内存中的存储

二.二维数组

1.二维数组的创建与初始化

(1)数组的创建

(2)数组的初始化

2.二维数组的使用

3.二维数组在内存中的存储

三.总结


一.一维数组

1.一维数组的创建和初始化

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

(1)数组的创建

创建方式:

type_t arr_name[const_n];

type_t 是数组的元素类型

[const_n] 是一个常量或常量表达式,用来指定数组的大小

例如我们创建int类型和char类型的数组:

int arr1[5];

int arr2[2+3];

char arr3[10];

**[ ]**内一定要是一个常量或者常量表达式。那么我们再来看一个数组创建:

int a = 5;

int arr[a];

上述数组的创建可以被允许吗???事实上这牵扯到C语言的版本问题。

C99之前 ,数组的大小只能用常量指定,但是在C99之后 引用了变长数组的概念,数组的大小便可以用变量来指定了。

但是博主现在所使用的VS2019,以及VS2022都是不支持变长数组的

(2)数组的初始化

初始化是指,在数组创建的同时给数组输入一些合理的初始值。

int arr[5];//已知数组大小时,可以只创建而不初始化

int arr1[10] = {1,2,3};//不完全初始化,剩余元素默认初始化为0

int arr2[] = {1,2,3,4};//创建大小未知的数组时,必须初始化,默认大小为元素个数

int arr3[5] = {1,2,3,4,5};//规范初始化,元素个数与数组大小一致

char arr4[3] = {'a',98,'c'};//字符初始化要用单引号,如果给的是数字,则存在数组里的实际是数字所对应的ASCII码值所对应的字符,例如98对应字符'b',所以实际存进数组的是字符'b'

char arr5[] = {'a','b','c'};//常规字符初始化,不满同样补0

char arr6[] = "abcdef";//直接输入字符串时,用双引号

如上,数组的初始化化有很多种方法,其中值得注意的是,arr5和arr6两种字符数组的初始化,其中arr5是单个字符的输入,arr6是字符串整体的输入,这样arr6便会比arr5多输入一个'\0'。

2.一维数组的使用

对数组的操作,则是通过下标引用操作符 '[ ]' 来实现。

如上图我们可以看到,数组中元素的实际顺序是从0开始的,也就是说,假如我们要操作数组的第5个元素,那就要用arr[4],而这个**'4'** 我们则称为是数组元素的下标

这里我们定义了一个char型的数组,char型数组也可以接收数字 ,只不过是想要打印出数字就必须用到**'%d'**。

如果我们想把数组的全部元素打印出来,只需要用到for循环

循环打印数组元素时,这里有一个陷阱,那就是我们的循环变量**'i'是数字元素的下标** ,而数组元素的下标是元素的实际顺序减1 ,所以这里的**'i'要从0开始,并且到9结束** ,所以限制条件是i < 10,而不是i <= 10否则就会打印出多余的错误的结果,造成 数组越界

同时我们也可以通过数组元素下标来对其值进行修改:

如上,我们将'5'改成'1'

3.一维数组在内存中的存储

cs 复制代码
#include<stdio.h>
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int i = 0;
	arr[4] = 1;
	for (i = 0; i < 10; i++)
	{
		printf("&arr[%d] = %p\n",i,&arr[i]);
	}
	return 0;
}

这里给大家补充一个小知识点,当我们要打印一个数据所存放的地址时,要用到**'%p'。**

由此我们可以看出,随着数组下标的增长,元素的地址也在有规律的增长,每个地址直接相差4个字节,而这正是一个int型数据所占用的字节数。因此我们可以得出结论:

数组在内存中是连续存放的

二.二维数组

二维数组与一维数组的区别并不大,下面我们就来具体介绍一下二维数组。

1.二维数组的创建与初始化

(1)数组的创建

int arr[3][4];

char arr[4][5];

double arr[5][6];

如果一维数组只是一条直线,那么二维数组就是一个矩形,第一个[]代表行,第二个[]代表列

(2)数组的初始化

int arr[3][4] = {1,2,3,4,5,6,7};//不完全初始化,会根据行数列数依次填充,不满补0

int arr1[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};//不规范初始化

int arr2[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};//规范初始化,每一行用一个大括号

int arr3[3][4] = {{1},{2,3},{4,5,6}};//不完全初始化,每一行空缺的位置补0

int arr4[][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};//省略行数初始化,会根据{}数来默认行数

int arr5[3][] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};//省略列数初始化,不允许,会报错

2.二维数组的使用

二维数组的使用同样是通过下标。

cs 复制代码
#include<stdio.h>
int main()
{
	int arr[3][4] = { {1,2,3,4},{5,6,7,8},{9,10,11,12} };
	printf("%d", arr[2][3]);
	return 0;
}

假如我们要打印这个二维数组的元素12,那么我们就要找到它所在的位置,如下图所示为2行3列

那么如果我们要遍历整个数组又该怎么办呢???

很简单,只需要用到嵌套循环便可:

cs 复制代码
#include<stdio.h>
int main()
{
	int arr[3][4] = { {1,2,3,4},{5,6,7,8},{9,10,11,12} };
	int i = 0;
	int j = 0;
	for (i = 0; i < 3; i++)
	{
		for (j = 0; j < 4; j++)
		{
			printf("%d ", arr[i][j]);
		}
		printf("\n");
	}
	return 0;
}

外层循环来控制行数内层循环来控制列数 ,这样便可以轻松实现二维数组的遍历,如果我们希望打印出来的格式为3行,那么我们就要在内层循环结束时输出一个'\n'来换行

3.二维数组在内存中的存储

cs 复制代码
#include<stdio.h>
int main()
{
	int arr[3][4] = { {1,2,3,4},{5,6,7,8},{9,10,11,12} };
	int i = 0;
	int j = 0;
	for (i = 0; i < 3; i++)
	{
		for (j = 0; j < 4; j++)
		{
			printf("&arr[%d][%d] = %p\n",i,j, &arr[i][j]);
		}
	}
	return 0;
}

我们同一维数组一样来看看二维数组是怎么在内存中存储的:

我们能够看出,二维数组的元素存储在内存中也是连续的,每一行的末尾与下一行的开头相连

事实确实如此,小伙伴们可不要理所当然的以为二维数组在内存中就是分行存放的,分行只是我们想象中的二维数组的具象化,但其实在内存中并不是。

二维数组的元素同样也是随着下标的增长,内存不断增加

三.总结

数组的讲解到这里就要结束啦,喜欢博主文章的小伙伴们不要忘记一键三连哦!

我们下期再见!

相关推荐
西猫雷婶26 分钟前
python学opencv|读取图像(二十一)使用cv2.circle()绘制圆形进阶
开发语言·python·opencv
kiiila26 分钟前
【Qt】对象树(生命周期管理)和字符集(cout打印乱码问题)
开发语言·qt
罗伯特祥38 分钟前
C调用gnuplot绘图的方法
c语言·plot
小_太_阳1 小时前
Scala_【2】变量和数据类型
开发语言·后端·scala·intellij-idea
直裾1 小时前
scala借阅图书保存记录(三)
开发语言·后端·scala
唐 城1 小时前
curl 放弃对 Hyper Rust HTTP 后端的支持
开发语言·http·rust
嵌入式科普2 小时前
嵌入式科普(24)从SPI和CAN通信重新理解“全双工”
c语言·stm32·can·spi·全双工·ra6m5
码银3 小时前
【python】银行客户流失预测预处理部分,独热编码·标签编码·数据离散化处理·数据筛选·数据分割
开发语言·python
从善若水3 小时前
【2024】Merry Christmas!一起用Rust绘制一颗圣诞树吧
开发语言·后端·rust
lqqjuly3 小时前
特殊的“Undefined Reference xxx“编译错误
c语言·c++