小伙伴们大家好,随着不断对c的学习,今天我们将学到有关数组的知识,好的废话不多说让我们开始今天的学习吧。
先列出我们今天要学哪些知识点吧:一维数组的创建和初始化,一维数组在内存中是怎么样存储的,二维数组的创建和初始化,二维数组在内存中是如何存储的,二维数组与一维数组的区别,数组越界的问题,数组作为函数参数相关问题(错误设计冒泡排序,解决办法以及正确设计)
在了解一维二维数组之前,我们先来谈谈什么是数组。数组是一组相同元素的集合。那么一维数组 我们该如何创建呢
好的从图来看
![](https://i-blog.csdnimg.cn/blog_migrate/261297eb72ad960f87d2069816a80f0e.png)
一个合格的一维数组需要数组名,数组类型,数组大小。这里需要注意的是数组大小不可以用变量来指定。在c99标准之前数组大小只能由常量来指定大小,在c99中引入了变长数组的概念,所谓变长数组就是数组大小可以由变量来指定,如图所示,但是呢由于vs比较傲娇,在vs中还是无法使用变长数组的。不过在vc6.0中可以使用,但是变长数组不能初始化。
![](https://i-blog.csdnimg.cn/blog_migrate/832446a678786be9e8b6a33e4a15be4e.png)
好的,接下来然我们一起了解一维数组的初始化吧
![](https://i-blog.csdnimg.cn/blog_migrate/3df80c75d74da226cf439541c3b15680.png)
![](https://i-blog.csdnimg.cn/blog_migrate/c150da44427880f14b19540970aa221a.png)
看图的话效果不错的,通过代码结果一眼就能看出完全初始化和不完全初始化的区别。当然数组类型不止由int型还有char型,char型一维数组有两种初始化的方式
![](https://i-blog.csdnimg.cn/blog_migrate/15b59b6b64559fc6974cb6d8400ae5f8.png)
那么这一种有什么区比呢,数组ch2中隐藏着一个‘0’,详情请看
接下来我们讨论一下一维数组在内存中是如何存储的,直接上图
![](https://i-blog.csdnimg.cn/blog_migrate/d8de88af22ae02843f20f1196e42b548.png)
通过图像我们可以知道一维数组在内存中连续存放的,并且随着下标的增大也由低地址到了高地址。
一维数组的讲解到此为止,来开始二维数组吧!!!
二维数组呢其实也并不复杂。一维是行,那么二维就是多行多列。那么二维数组该如何初始化呢,这种情况依旧需要图来说明 。二维数组也分为完全初始化和不完全初始化,也和一维数组相似,不完全初始化剩余部分默认为0;
![](https://i-blog.csdnimg.cn/blog_migrate/01ae6375846e436576292624ccc49cdd.png)
上面得是创建,下面的是初始化
![](https://i-blog.csdnimg.cn/blog_migrate/18846d7f4eabe009c841390731faee2f.png)
![](https://i-blog.csdnimg.cn/blog_migrate/67f689e6a3d363cbc2f785b5c80e789a.png)
接下来开始讨论一下二维数组在内存中如何存储,依旧是直接上图。先上代码图,再画的图。这里我们会发现第一行的最后一个地址和第二行的第一个地址相差四个字节。这里可能有小伙伴们会迷糊了,那顺便来讲讲吧。内存会被划分成一个个的内存单元,每个内存单元的大小是一个字节。这里之所以会么偶各元素跳过四个字节,是因为int型的大小是4个字节。倘若数组类型是char型,那么每个元素的地址就将会相差一个字节(因为char型的大小是1个字节)。回归正题,那么我们可以把其连续起来写,上图。从图中会发现二维数组在内存中的存储也是连续的·。
![](https://i-blog.csdnimg.cn/blog_migrate/f6109441740ec7a776af17f4391ef667.png)
到此,我们已经来到了一维与二维的区别与联系,联系:二者在内存中的存储都是连续的,不完全初始化时剩下部分默认为0.区别:一维是一行,二维是多行多列。接下来是数组越界问题,什么是数组越界呢?在讲这个之前,我们先来看一个代码。数组使用是通过引用下标(引用下标需要下表引用操作符[ ])来实现并且下标是从0开始的,最后一个元素的下标比元素个数少1。数组越界,当程序员写代码是数组的下标不是从0开始而是-1,-2等,或者数组元素下标比数组元素不符。当发生数组越界错误时,程序不会报错但是显示显示结果是有误的。这种需要程序员自己来检查代码。所以各位程序员大佬们写代码时要注意噢
![](https://i-blog.csdnimg.cn/blog_migrate/5fb6f01bd395994a8fdfcbe8c440da25.png)
第二个图是发生数组越界·
![](https://i-blog.csdnimg.cn/blog_migrate/ac29fe61dbee2bd9ba9978b86d6b3b54.png)
终于我们来到最后一个问题:数组作为函数参数。坚持到这的勇士们还有多少呢?么么哒,让我们一起开始学习吧。
数组作为函数参数,研究这个问题我们要通过一道冒泡排序题来说明其中那个的缘由,在开始之前我们先来说说什么是冒泡排序,冒泡排序的核心思想:两两相邻的元素进行比较。简单一提核心思想,上代码解题
![](https://i-blog.csdnimg.cn/blog_migrate/7683853aea22c086564bcdbc2ea0b3e4.png)
![](https://i-blog.csdnimg.cn/blog_migrate/6835c4dd2a609fb19dec03641c9210ac.png)
最后运行结果,并没有改变
![](https://i-blog.csdnimg.cn/blog_migrate/9ca25883886d23304253bb8b78108cff.png)
这里我们发现,打印出来的结果还是原先的并没有改变,这是为什么呢?这是因为数组作为函数参数时传过去的是首元素的地址。上图来看,会发现打印过一模一样。但是这种也有两个例外,第一个是&(数组名)这里表示拿的是整个数组的地址而并不是首元素地址口说无凭,上代码
![](https://i-blog.csdnimg.cn/blog_migrate/0c6cdbffe7bf8fba15f4365f0fe64868.png)
在这段代码中,我们发现,诶?不对呀它们三个结果都一样,是不是&(数组名)也是表示数组首元素的地址呀?nonono,这种想法是不对的,当它们都加+1时就不同。上代码
![](https://i-blog.csdnimg.cn/blog_migrate/c5d97ab2ea3a803f354ccdf7f374734e.png)
。这里跳过的二八,是十六进制的二八,一转换值为40.&(数组名)+1跳过的是整个数组。接着来说,第二个例外则是sizeof(数组名),通过代码我们可以清楚知道计算的是整个数组的大小。
![](https://i-blog.csdnimg.cn/blog_migrate/987133de922ffbd4d2b949df09abf680.png)
OK,接下来就让我们一起来这个正确设计冒泡排序吧
![](https://i-blog.csdnimg.cn/blog_migrate/7fcf3fe0799a74a7f626bbbb19a5d727.png)
![](https://i-blog.csdnimg.cn/blog_migrate/f72cd1285e0b3403ed8ffbd4971055c9.png)
最后运行结果
![](https://i-blog.csdnimg.cn/blog_migrate/9592038d85a293e7e1bedf3cb3f49102.png)
OK,以上就是所有的内容。创作不易还望各位看官老爷留下赞赞和评论喏。么么哒