当前位置: 首页 > news >正文

C语言入门(九):二维数组的介绍

一:二维数组的结构

1.二维数组的概念

前⾯学习的数组被称为⼀维数组,数组的元素都是内置类型的,如果我们把⼀维数组做为数组的元 素,这时候就是⼆维数组,⼆维数组作为数组元素的数组被称为三维数组,⼆维数组以上的数组统称 为多维数组。

具体结构如下

2.二维数组的原型

原型:type arr_name[常量值1][常量值2]
type是元素类型    arr后面的是数组名字             常量1指行       常量2指列

代码如下

 int表⽰数组的每个元素是整型类型

arr是数组名,可以根据⾃⼰的需要指定名字 data数组意思基本⼀致。

三行七列,总共是3行,每一行有7个元素

char ch[3][7]; 

 三行五列

int arr[3][5];   //三行五列

二行八列

double date[2][8];     //二行八列

二:二维数组的初始化

在创建变量或者数组的时候,给定⼀些初始值,被称为初始化。 那⼆维数组如何初始化呢?像⼀维数组⼀样,也是使⽤⼤括号初始化的。

代码如下

1.不完全初始化(和一维初始化一样)

用监视我们可以看到前三个元素是1,2,3后面没有初始化的元素全部会是0来代替

int main()
{int arr1[3][5] = {1,2,3};//用监视我们可以看到前三个元素是1,2,3后面没有初始化的元素全部会是0来代替int arr2[3][5] = {0};//全部是0return 0;
}

结果可以看这个来进行分析、

下面这个图就是我们具体的结构图,上面代码结果的下面详细结构图

2.完全初始化

部分代码如下

int main()
{int arr3[3][5] = { 1,2,3,4,5  , 2,3,4,5,6  , 3,4,5,6,7 };return 0;
}

结果下图

3.按照⾏初始化

指定某个位置进行初始化,这里我们是第一行放1,2由于我们每一行有5个元素,后面我们没有给定的初始化全部用0代替

int date[3][5] = { {1,2},{3,4},{5,6} };//指定某个位置进行初始化,这里我们是第一行放1,2由于我们每一行有5个元素,后面我们没有给定的初始化全部用0代替

注意:数组在初始化的时候,   行可以省略,列不可以省略

int main()
{int arr5[][5] = { 1,2,3 };//只有1行,监视结果:1,2,3,0,0int arr6[][5] = { 1,2,3,4,5,6,7 };//2行     第一行是1,2,3,4,5第二行是6,7,0,0,0int arr7[][5] = { {1,2},{3,4},{5,6} };//3行   第一行1,2,0,0,0第二行 3,4,0,0,0第三行  5,6,0,0,0  return 0;                
}

只有1行,监视结果:1,2,3,0,0

int arr5[][5] = { 1,2,3 };//只有1行,监视结果:1,2,3,0,0

2行     第一行是1,2,3,4,5
第二行是6,7,0,0,0

int arr6[][5] = { 1,2,3,4,5,6,7 };//2行     第一行是1,2,3,4,5第二行是6,7,0,0,0

3行   第一行1,2,0,0,0
第二行 3,4,0,0,0
第三行  5,6,0,0,0  

	int arr7[][5] = { {1,2},{3,4},{5,6} };//3行   第一行1,2,0,0,0第二行 3,4,0,0,0第三行  5,6,0,0,0  

结构图如下

三:⼆维数组的使用

1.⼆维数组的下标

当我们掌握了⼆维数组的创建和初始化,那我们怎么使⽤⼆维数组呢? 其实⼆维数组访问也是使⽤下标的形式的,⼆维数组是有⾏和列的,只要锁定了⾏和列就能唯⼀锁定 数组中的⼀个元素。 C语⾔规定,⼆维数组的⾏是从0开始的,列也是从0开始的,如下所⽰:

int arr[3][5] = {1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7};

结构图如下

图中最右侧绿⾊的数字表⽰⾏号,第⼀⾏蓝⾊的数字表⽰列号,都是从0开始的,⽐如,我们说:第2 ⾏,第4列,快速就能定位出7

#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;]

输出的结果如下

2.用下标来打印二维数组的元素(和一维数组一样,下标的  行  列 都是从0开始的)


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[1][3]);//结果是5return 0;
}

输出结果如下

3.打印我们的所有元素的方法,利用循环来打印

完整代码如下

int main()
{int arr[3][5] = { 1,2,3,4,5  , 2,3,4,5,6  , 3,4,5,6,7 };int i = 0;//将  行  存放起来for (i = 0; i < 3; i++){int j = 0;//将   列   存放起来for (j = 0; j < 5; j++){printf("%d ", arr[i][j]);//将行 列 打印出来}printf("\n");//这里的printf可以省略,但是为了好看,所有我就加上了}return 0;
}

解析

将  ‘行’ 存放起来

int i = 0;//将  行  存放起来

将   列   存放起来

int j = 0;//将   列   存放起来

这里的printf可以省略,但是为了输出的结果好看,所有我就加上了

}printf("\n");//这里的printf可以省略,但是为了好看,所有我就加上了

将行 列 打印出来

printf("%d ", arr[i][j]);//将行 列 打印出来

输出结果如下

四:二维数组的输入和输出

访问⼆维数组的单个元素我们知道了,那如何访问整个⼆维数组呢? 其实我们只要能够按照⼀定的规律产⽣所有的⾏和列的数字就⾏;以上⼀段代码中的arr数组为例,⾏ 的选择范围是0~2,列的取值范围是0~4,所以我们可以借助循环实现⽣成所有的下标。

1.输入

int main()
{int arr[3][5] = {0};int i = 0;for (i = 0; i < 3; i++)//产生行号{int j = 0;for (j=0; j<5; j++)//产生列号{scanf("%d ", &arr[i][j]);//输入数据,这里的行和列可以反过来,就是竖着打印也是可以的}}

给数组进行初始化

int arr[3][5] = {0};

输入数据,这里的行和列可以反过来,就是竖着打印也是可以的

scanf("%d ", &arr[i][j]);//输入数据,这里的行和列可以反过来,就是竖着打印也是可以的

2.  输出

	for (i = 0; i < 3; i++)//产生行号{int j = 0;for (j = 0; j < 5; j++)//产生列号{printf("%d ", arr[i][j]);//输出数据}printf("\n");}return 0;

完整的二维数组的输入与输出的代码

int main()
{int arr[3][5] = {0};int i = 0;for (i = 0; i < 3; i++)//产生行号{int j = 0;for (j=0; j<5; j++)//产生列号{scanf("%d ", &arr[i][j]);//输入数据,这里的行和列可以反过来,就是竖着打印也是可以的}}//	输出for (i = 0; i < 3; i++)//产生行号{int j = 0;for (j = 0; j < 5; j++)//产生列号{printf("%d ", arr[i][j]);//输出数据}printf("\n");}return 0;
}

输出的结果如下

五:二维数组在内存中的存储

像⼀维数组⼀样,我们如果想研究⼆维数组在内存中的存储⽅式,我们也是可以打印出数组所有元素 的地址

代码如下

int main()
{int arr[3][5] = { 0 };int i = 0;//把数组每个元素的地址打印出来for (i = 0; i < 3; i++){int j = 0;for (j = 0; j < 5; j++){printf("&arr[%d}[%d] = %p\n",  i,j,  &arr[i][j]);}}return 0;
}

把数组每个元素的地址打印出来

printf("&arr[%d}[%d] = %p\n",  i,j,  &arr[i][j]);

输出的结果

从输出的结果来看,每⼀⾏内部的每个元素都是相邻的,地址之间相差4个字节,跨⾏位置处的两个元 素(如:arr[0][4]和arr[1][0])之间也是差4个字节,所以⼆维数组中的每个元素都是连续存放的。 如下图所⽰:

了解清楚⼆维数组在内存中的布局,有利于我们后期使⽤指针来访问数组的学习。

六:. C99中的变⻓数组

在C99标准之前,C语⾔在创建数组的时候,数组⼤⼩的指定只能使⽤常量、常量表达式,或者如果我 们初始化数据的话,可以省略数组⼤⼩

这样的语法限制,让我们创建数组就不够灵活,有时候数组⼤了浪费空间,有时候数组⼜⼩了不够⽤ 的。 C99中给⼀个变⻓数组(variable-lengtharray,简称VLA)的新特性,允许我们可以使⽤变量指定 数组⼤⼩。 请看下⾯的代码

上⾯⽰例中,数组 arr 就是变⻓数组,因为它的⻓度取决于变量 n 的值,编译器没法事先确定,只 有运⾏时才能知道 n 是多少。 变⻓数组的根本特征,就是数组⻓度只有运⾏时才能确定,所以变⻓数组不能初始化。它的好处是程 序员不必在开发时,随意为数组指定⼀个估计的⻓度,程序可以在运⾏时为数组分配精确的⻓度。有 ⼀个⽐较迷惑的点,变⻓数组的意思是数组的⼤⼩是可以使⽤变量来指定的,在程序运⾏的时候,根 据变量的⼤⼩来指定数组的元素个数,⽽不是说数组的⼤⼩是可变的。数组的⼤⼩⼀旦确定就不能再 变化了。 遗憾的是在VS2022上,虽然⽀持⼤部分C99的语法,没有⽀持C99中的变⻓数组,没法测试;下⾯是 我在gcc编译器上测试,可以看⼀下。

第⼆次测试,我给n中输⼊10,然后输⼊10个数字在数组中,并正常输出

七:数组练习

问题:多个字符从两端移动,向中间汇聚

完整代码如下


int main()
{char arr1[] = "welcome to bit !!!!!!";char arr2[] = "***************************";int left = 0;//左边的字符int right = strlen(arr1) - 1;//右边的字符while (left<=right){arr2[left] = arr1[left];//将arr1左边的字符放到arr2下面左边对应的字符arr2[right] = arr1[right];//和上面一样,这里是和右边对应的printf("%s\n", arr2);Sleep(500);//单位是毫秒,需要一个头文件 #include<windows.h>,代码程序会每隔1000毫秒进行下一个代码system("cls");//system是给电脑下指令的意思,cls是清理输出屏幕的信息left++;right--;}return 0;
}

左边的字符

int left = 0;//左边的字符

右边的字符

int right = strlen(arr1) - 1;//右边的字符

将arr1左边的字符放到arr2下面左边对应的字符

和上面一样,这里是和右边对应的

arr2[left] = arr1[left];//将arr1左边的字符放到arr2下面左边对应的字符
arr2[right] = arr1[right];//和上面一样,这里是和右边对应的

单位是毫秒,需要一个头文件 #include<windows.h>,代码程序会每隔1000毫秒进行下一个代码

Sleep(500);//单位是毫秒,需要一个头文件 #include<windows.h>,代码程序会每隔1000毫秒进行下一个代码

system是给电脑下指令的意思,cls是清理输出屏幕的信息

system("cls");//system是给电脑下指令的意思,cls是清理输出屏幕的信息

八:数组的二分查找(折半查找)

注意:使用的前提是,必须是连续有序的数组

这里我们先用普通的查找方式

int main()
{int arr[] = { 1,2,3,4,5,6,7,8,9,10 };int k = 7;//在数组中找数字7int i = 0;int sz = sizeof(arr) / sizeof(arr[0]);int flag = 0;for (i = 0; i < sz; i++){if (k == arr[i]){printf("找到了,下标是:%d", i);flag = 1;//非0为真break;}}if (flag == 0)//0为假{printf("超出范围\n");}return 0;
}

范围里面的情况

超出范围的情况(将k设置为范围之外的元素17)

使用二分查找(折半查找)方式

完整代码如下

这里的输出的结果和上面的一样,超不超出范围取决于k和arr的元素是多少

这里的flag是表示真假的意思

int main()
{int arr[] = { 1,2,3,4,5,6,7,8,9,10 };int k = 100;//在数组中找数字7int i = 0;int sz = sizeof(arr) / sizeof(arr[0]);int flag = 0;int left = 0;//左下标int right = sz - 1;//右下标while (left <= right){int mid = (left + right) / 2;//计算中间数的下标,mid是中间的意思int mid = left + (right - left) / 2;//这个计算中间数的下标更好一点if (arr[mid] < k)//  arr[mid]  是我们中间下标的那个数,将它与我们要找的那个数 k 进行比较{left = mid + 1;//当我们的中间数的下标小于k的时候,我们就可以知道左边所有的数都不符合我们那个数,因为小了,于是我们要从右边在进行一次二分查找,依次循环}else if (arr[mid] > k)//同上,这里是大于k的情况{right = mid - 1;}else{flag = 1;printf("找到了,下标是%d\n", mid);break;}}if (flag == 0){printf("超出范围了\n");}return 0;
}   

以上就是关于二维数组的全部内容了

http://www.dtcms.com/a/466379.html

相关文章:

  • 深圳网站设计公司的seo优化的常用手法
  • 西安三桥网站建设重庆市建设考试报名网站
  • Unicode编码中的零宽空格0x200B
  • 实战指南:Stable Diffusion 图像生成模型
  • PyTorch的AI框架小白入门的学习点
  • 办公网站模板网站建设微信官网开发
  • 信誉好的合肥网站建设全网网站建设维护
  • 建设部网站 标准下载如何判断网站做的关键词
  • 诺奖相关的调节性T细胞怎么养?
  • 旺道网站优化重庆ppt制作
  • ps免抠素材网站大全免费制作h5页面平台
  • 反激电源实际设计
  • Java优雅停机指南
  • DDoS攻击演变趋势与企业应对策略
  • 新版本 python 3.14 性能到底如何?
  • 郑州网站推广平台一个外国人做的破解游戏网站
  • 合肥网站建设方案咨询wordpress本地搭建网站a
  • .net电子商务网站开发wordpress展示图片不显示
  • 射频技术领域的领航者,昂瑞微IPO即将上会审议
  • VonaJS AOP编程:全局中间件全攻略
  • 物联网技术第四节课学习笔记
  • 【MT6631】MT6631 WiFi跑流ping包延迟大问题解决方案
  • 一个网站做两种产品文创产品
  • 三坐标测量仪:汽车冲压件±0.3mm形位公差控制的解决方案
  • Notepad++实现列编辑/列粘贴
  • 建设大淘客网站厦门哪些企业做视频网站的
  • JS进阶(二):创建对象的方式、构造函数、实例成员静态成员、内置构造函数(Object、Array、String、Number)
  • 半监督学习:机器学习中的“半指导”学习范式
  • 广州网站建设 八爪鱼高层网络架构
  • [SIGCOMM‘25] Revisiting RDMA Reliability for Lossy Fabrics