目录
!!!!!!!!!!!!!! 下 标 !!!!!!!!!!!!!!!!!
文章概要
本章讲述暂时只讨论一维数组和二维数组;多维数组(二维及二位以上),数组作为函数参数等章节不参与此次讨论,但会在能力范围内讲的明白。感谢观看(本人为技术萌新,只讨论在实践过程中的心得,如有问题请及时指出)
数组就类似与把相同的类型归类到一起,袜子和袜子放在一起,衣服和衣服放在一起,需要多少拿出来多少。
文章大致分为:1.数组的定义与创建
2.数组的多种初始化
3.数组的使用
4.数组的内存存储
对应标题在目录之中,如需查看,请点击相应章节观看。
提示:以下是本篇文章正文内容
一、一维数组
1.一维数组的定义与创建
数组的定义:数组是一组相同类型的集合。举个例子:你看到你的房间比较乱的时候,人最先想到的整洁的方式是整理归类,比如你看到床上衣服和袜子在一起,你会讲袜子和袜子放在一起,衣服和衣服放在一起,而衣服和衣服的归类,袜子和袜子的归类,便称为相同类型的集合。
数组的创建方式:type arr_name[常量值]
类型+数组名[元素值/下标]
创建例子:int arr[10];
double arr[10];
char arr[10];
这就是数组最简单的创建,也是萌新入门数组的基础
在这里值得一提的是!!!
下表是从0开始的,具体应用请见2.数组的多种初始化
2.数组的多种初始化
首先先来说数组的一种初始化:指在创建的基础上给一个或多个合理的值;而每个类型的初始化又存在差异,本章的初始化我们就来讨论其差异性。
一维数组的初始化图
a.整型数组的初始化
初始化也分多种,先说整型数组分为完全初始化和不完全初始化
完全初始化是指数组的常量值(元素值)与后面给定的值的个数(元素个数)一致
不完全初始化是指数组的常量值(元素值)与后面给定的值的个数(元素个数)不一致
废话不多说上图:
完全与非完全的初始化图
还有一个
int arr2[]={0};//这种现在只有一个元素,根据代码块的元素个数的多少,定义元素值
很容易看出int arr[10]的后面代码块中的元素个数为1, int arr2[10]的元素个数为10
故数组名为arr的数组为不完全初始化数组,数组名为arr2的数组为完全初始化数组。
b.字符数组的初始化
字符数组也分完全和非完全,参照上例,但是在这里我们重点讨论的是字符数组的3种方式的初始化,我们以问答形式来解答
下面就是的3种书写方式:
// char ch[9] = {0};
// char ch2[9] = { 'a','b','c'};
// char ch3[9] = "abc";
探索方法:F10进入分布调试页面,F11分布调节,在监视页面,输入数组名,观看其储存形式。
问题一:字符类型的ch数组为首位‘0’但是在内存中其他元素是什么哪?,总不可能为整型的吧?
字符数组ch监视图
解答:观察监视图可知:字符数组的首元素0以‘/0’的方式储存在内存中。
问题二:字符类型的数组ch2中的'a','b','c'是怎么储存的,以及ch3和ch2如此相近,是怎么储存的??相同吗?
字符数组ch2和ch3的初始化监视图
解答:监视图可知,两者书写方式虽然不同,但是储存形式是相同的,所以在初始化书写中,是一样的,但要注意的是ch2中的字符是单引号'a',ch3中的数组是双引号""
由于篇幅有限,其他类型请施主自行探索(说人话:有点小累)
———————————————————————————————————————————
!!!!!!!!!!!!!! 下 标 !!!!!!!!!!!!!!!!!
这是新手很容易犯的错误知识点,本萌新也是,一定要记得下标从0开始,
请让我为大家讲解:
int arr[10]={1,2,3,4,5,6,7,8,9,10}
元素 1,2,3,4,5,6,7,8,9,10
下标 0,1,2,3,4,5,6,7,8, 9
虽然元素是1—-10,但是下标是0——9,所以在引用是数组是从arr[0]——arr[9],没有arr[10]
这一点一定要注意!!!!!
———————————————————————————————————————————
3.数组的使用
能够定义数组,那么就要提到如何使用数组和数组的输入和输出了
即三个模块1.一维数组的引用 2.一维数组的输入3.一维数组的输出
1.数组的引用
假设定义了 int arr[10]={1,2,3};
int c=0;
引用:c=arr[9];
2.数组的输入
因为数组是一个多数字的集合,不可能一次性输完,所以要用到循坏语句进行循环输入,讲每个输入的值储存到对应的数组的元素中,直到达到元素值为止。
一个元素一个元素的输入,中间用空格隔开哈!!!!!
for (i = 0; i < 10; i++)
{
scanf("%d", &arr[i]);
}
3.数组的输出
与输入类似,在循坏的基础上逐个进行输出,逐个将每个元素进行输出。
一个元素一个元素的有序输出!!!!
for (i = 0; i < 10; i++)
{
printf("%d", &arr[i]);
}
4.一维数组的内存存储
前提引入:在x64的环境下,数组地址为很长,不便于分析,所以在vs2022的编译器中使用下x84环境下观察数组地址。故在此坏境下,地址为16进制
必备引入知识:&为取地址操作符,可以将数组的储存地址取出来,更便于观察。
for (i = 0; i < 10; i++)
{
scanf("%d", &arr[i]);
}
内存的地址图
观察情况:最后两位分别为60 64 6C 70 74 78 7C 80 84
在16进制每位的地址相差4,而整型的每个字节长度为4,故可以推断,
1.数组的地址是连续存放的;
2.随着数组下标的增长,数组的地址也是从低到高变化的;
二、二维数组
1.、二维数组的定义与创建
1.二维数组的定义
如果说一维数组是以数字为元素的集合
如:
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
其中每个元素都是int类型
那二维数组是以一维数组为元素的集合
如
int arr[3][5]={1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7}
1 | 2 | 3 | 4 | 5 |
2 | 3 | 4 | 5 | 6 |
3 | 4 | 5 | 6 | 7 |
这个数组可以看作由三个arr数组组成的一个二维数组。
三个一维数组可以看为
arr1[5]={1,2,3,4,5}
arr2[5]={2,3,4,5,6}
arr3[5]={3,4,5,6,7}
但实际是二维数组是一维数组的数组.
2.二维数组的创建
int arr[9][10];
int arr[][10];
我们 把它读为3行10列,其中行可以省略(不会报错),而列不可以省略;
如果缺少列会报错:“缺少下标”程序无法运行";
缺少行则不会报错;
2.二维数组的多种初始化
由于篇幅原因,我们只讨论int类型的二维数组
int data[3][5] = { 1,2,3,4,5,2,3,4,5,3,4,5,6 };//以一维数组的数字元素定义的二维数组的初始化
int data2[3][5] = { {1,2} ,{3,4},{5,6} };//以多个一维数组为元素的二维数组的初始化
int data3[][5] = { 1,2,3,4,5,6,7,8 };//省略行的定义的二维数组(行可以省略,列不可以省略)
1.我们用一维数组的探索方法来看看二维数组的存储是怎么样的,是否可以运行 ;
在监视窗口我们可以发现
1.data数组的元素是根据行和列的来进行排列的
2.data2数组因为前面加入了"{}"号,所以会把一个“{}”的元素认为是一个一维数组
3.有同学就会疑问了,那为什么data3的的排列会是两行?
其实你定义了列了,当元素到达列数值之后,编译器会自动换行,但这取决于你定义的二维数组元素个数的多少
三种初始化方式,每种初始化方式都会在实际应用中发挥不同的作用;
3.二维数组的使用
1.二维数组的引用
假设定义了int data[3][5] = { 1,2,3,4,5,2,3,4,5,6,3,4,5,6,7};的二维数组
如何引用哪?
printf("%d\n",arr[1][2]);
欸嘿,也许你会认为了,这打印的一定就是1行3列的那个数字
stop!!!
stop!!!
stop!!!
还记得数组的下标从0开始吗?
所以 [1][2] 对应的其实是2行3列
我们可以画下图看一下
0 | 1 | 2 | 3 | 4 |
横标
0 |
1 |
2 |
竖标
1 | 2 | 3 | 4 | 5 |
2 | 3 | 4 | 5 | 6 |
3 | 4 | 5 | 6 | 7 |
数组元素
故打印第二行第4列(标红的数字)
2.二维数组的输入与输出
二维数组的输入讲解:因为二维数组是输入的时候需要两个值(行,列)确定数组具体储存到哪里。(类似于平面x值y值确定一个点,然后给这个点赋值)
同时还需要保证能够输入循坏,保证每一个数组元素都能赋值。所以我们采用循坏的方式进行输入,同理输出也是一个道理。(不循环就只能输入一个数了)
输入与输出的代码图
循坏讲解:外层循环保证行的输入与输出,内层循环保证列的输入与输出。
每行输入完,在进入下一行;
4.数组的内存存储的地址
(欸嘿!刷到这里的同学建议先看一维数组的内存存储,这样你会很好理解
okk内存存储的地址的前提引入和须备知识,我就照抄了哈)
前提引入:在x64的环境下,数组地址为很长,不便于分析,所以在vs2022的编译器中使用下x84环境下观察数组地址。故在此坏境下,地址为16进制
必备引入知识:&为取地址操作符,可以将数组的储存地址取出来,更便于观察。
废话不多说,上图
代码:printf("&data[%d][%d]=%p\n", i, j, &data4[i][j]);
内存地址代码运行所示
有人认为二维数组的地址间隔是列数*4,其实不是,因为在储存的时候一维数组和二维数组一样,都是以整型元素为单位储存的,一个整型4个字节,所以间隔还是4哦
欸嘿,写完喽,也许你可能看完了文章,我在这里表示感谢 ,文章中我个人感觉还是有很大纰漏的,作为萌新,查漏意识不太强,哈哈哈哈,但是我会努力的,也希望看到这篇文章的人生活越来越好。一杯酒,敬你也敬我!!!!
总结
问题1.关于数组的类型?
解答:其实类型这个东西都一样,创建时,去掉名字就行
比如:int c;类型就是int;
数组:int arr[10];类型就是 int[10];二维数组也一样。
问题2:其他类型数组的初始化
解答:个人感觉初始化的第一个元素跟变量一样,什么类型就什么样子
比如:double arr[10]={0.0}就这种 二维数组也相同,毕竟二维数组是以一维数组为元素的数组
问题三:strlen和sizeof的区别
通俗点:strlen头文件<string.h>打印的是字符串的个数
sizeof是操作符是以字节形式打印了操作数的存储大小,就是数组里面有多少给元素,就把元素*类型的字节。
sizeof像是拿着苹果送人,胖人给两个,瘦的给一个,然后最后算一算今天送出了多少苹果。