目录
一、数组
(一)概念
数组是一种相同类型元素的集合。
(二)分类
数组分为一维数组和多维数组,多维数组一般比较多见的是二维数组。
(三)注意事项
1.数组中存放的是1个或者多个数据,但数组元素个数不能为0
2.数组中存放的多个数据,类型是相同的
3.数组也有类型。如:数组arr的类型是int [10]
4.可以明确元素内容而不明确数组大小,也可明确数组大小而不明确元素内容。
二、一维数组
(一)基本语法
type:指定的是数组中存放数据的类型,可以是char等类型,也可以是自定义的类型
arr_name:指的是数组名的名字,可自定义,但尽量要起的有意义
(二)下标以及访问方法
例如,当想要知道arr[5]的内容是什么,可以使用“ printf("%d", arr[5]) ”来实现。其中,我们将[ ]这个符号称为下标引用符。
如果想要将数组中的所有内容打印出来,这需要循环语句。以下是以for循环来实现的:
当然,输入也是一样。
(三)初始化
使用大括号进行。分为不完全初始化和完全初始化。
(四)一维数组在内存中的存储
数组是如何在电脑中储存的呢?我们可以通过打印数组的地址来了解。
由此,我们可以得出结论:一维数组在内存中应该是连续存放的。
%p 打印地址的专业用,特点是以16进制的形式进行打印,同时最前面的0不会省略
int 4个字节
%x 是以16进制的形式打印(若想将地址变为大写的,使用%X就可以)
同时,我们还可以用%x打印:
大家可以看到用%p和%x打印的区别。
当然,如果大家想打印出0x,可以在%和x中间加上#,就可以实现这一效果:
另外,为了呈现美观,这里选择的是x86。
x86 —— 32位环境 地址短些
x64 —— 64位环境 地址长些
三、二维数组
(一)二维数组的概念
数组的元素都是内置的,如果我们把一维数组作为数组的元素,这时候便是二维数组;以二维数组作为数组的元素,便称为三维数组;二维数组以上的数组统称为多维数组。
(二)二维数组的创建
二维数组是如何定义的呢?
解析上面的信息(以第一个为例子):
double表示数组的每个元素是double类型
arr是数组名,可以自行创建,建议有意义一些,方便日后检查。
2表示数组有2行
4表示数组有4列
(三)二维数组的初始化
1.分为完全初始化和不完全初始化,不完全初始化的,剩余的元素默认初始化为0。
当我们想指定元素的所在行时,可以使用大括号{},例如:
如果我们使用(),会如何呢?
1和3去哪了?
实际上,当我们们使用()来分组时,其便成了逗号表达式。程序在读到这里时,会从左向右依次计算,结果会变成最后一个表达式,也就是2和4。
2.初始化要进行省略时,只能省略行,不能省略列。
(四)二维数组的下标
4的坐标为(1,2)。我们试试打印出来。
(五)二维数组的输入与输出
(六)二维数组在内存中的存储
我们可以通过打印二维数组所有元素的地址,来了解二维数组在内存中的存储。
从输出的结果来看,每一行内部的每一个元素都是相邻的,地址之间相差4个字节,跨行位置处的两个元素(如arr[0][4] 和 arr[1][0]之间也是4个字节)。
结论:二维数组在内存中是连续存放的。
这也再次强调了:二维数组初始化时可以省略行,但绝对不能省略列——比如,(0,4)后面紧跟着(1,0)。
四、C99中的变长数组
C99标准出来之前,C语言在创建数组的时候,数组大小的指定只能使用常量,或者在初始化数据时,可以省略数组大小。这样的语法限制,就使得我们创建数组不够灵活,数组过大会浪费空间,数组过小不够用。
于是,C99中,变长数组(简称VLA)出现了。
它的新特性可以允许我们使用变量指定数组大小(而不是数组的大小是变化的)
请看下面的代码:
例子中,arr就是变长数组,因为它的长度取决于变量n的值,编译器无法事先决定,只能在运行时才知道n为多少。 (变长数组不能初始化)
但是vs2022不支持C99的变长数组,下面是我在小熊猫上进行的测试:
五、sizeof计算数组元素个数
以此为例子,我们会发现到目前为止,我们所接触到的数组的长度都是被锁定的。那么有什么方法,能够计算出数组的元素个数,而不是我们所看到的10呢?
我们可以使用sizeof。
(一)sizeof的概念
sizeof 是C语言的一个关键字,可以用来计算类型或者变量大小的,也可以用来计算数组的大小。
如:
输出的结果为40,是数组所占内存空间的总大小,单位是字节。(这就和前面所提到int来呢西起来了)
但我们想知道的是,一个数组的大小。
值得一提的是,strlen用于求字符串的长度,也只能用于求字符串的长度。
我们还可以用别的表示方法:
(二)sizeof计算数组元素大小的基本运用
六、练习
(一)多个字符从两端移动,向中间汇聚
那么,用sizeof又有什么区别呢?
从定义上看,sizeof计算的是数组所占的空间内存大小,单位是字节;而strlen求的是字符串的长度,统计的是字符串\0之前的字符个数。因此,如果想用sizeof,那么里头的right就需要改动。
如下图所示:
(二)二分查找
如何在一个有序的数组中查找指定的内容,是否存在,存在则打印下标,不存在则说明不存在。
可惜的是,这样的效率比较低。那么还有什么更好的方法吗?
我买了一件衣服,朋友好奇衣服的价格,我说不超过200元。朋友显然不会从1开始慢慢猜,一般会从100左右开始猜,猜后看是大了还是小了,再进行猜测。这就是折半查找,也可以称作二分查找。
写作此文,我深感启发。希望它也能触动你的心弦