C语言——带你玩转数组

简介: C语言数组基础知识

 

前言😄

一维数组⭐️

一维数组的创建🍁

变长数组🍁

初始化🍁

使用🍁

越界问题🍁

在内存中的存储🍁

拓展:sizeof和strlen()的区别🍁

怎么理解sizeof是一个操作符?✅

二维数组⭐️

二维数组的创建🍁

初始化🍁

使用🍁

在内存中的存储🍁

数组作为函数参数⭐️

错误的冒泡排序🍁

数组名🍁

正确的冒泡排序🍁

结束语😄


前言😄

Hello,大家好啊,我们又见面了,如果你还在为C语言的数组而苦恼,如果你还在不知道怎么学习

数组的知识而迷茫,那请认真看完这篇博客,今天我将通过这一篇博客来介绍数组的相关内容,本

篇博客内容涉及广,且十分充实,全程高能!记得不要走神哦!如果觉得不错的话,为了防止迷

路,建议收藏哦,让我们一起学习,一起进步吧。❤️请允许我在这里㊗️广大一线工作者们、各行

各业劳动者们,以及大家劳动节快乐!

image.gif编辑


🎥下面我将通过一维数组的创建初始化、使用,存储开始,逐渐过渡到二维数组的内容,层层递

进,不断深入,让大家更好的去理解数组,夯实自身的基础,而不是填鸭式装满知识,对内容感到

枯燥。☀️


一维数组⭐️

一维数组的创建🍁

说到数组啊,我们首先得来先理解数组是什么意思:

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

为什么会有数组的出现?我们已经知道,变量都是单个的,个体的,但是如果当我们需要使用到同

一类型的多个变量时,这时候,我们就可以用数组来存放,而不是一个个去创建。这就是使用数组

的好处,关键是在于相同类型的元素。🔔

数组创建的基本方式:

type  arr_name   [const];

//type 是指数组的元素类型

//const 是一个常量表达式,用来指定数组的大小

我们可以来举个例子看一看:

image.gif编辑

我们可以根据类型创建出不同类型的数组,同时也可以常量来指定数组的大小。

变长数组🍁

长数组(variable-length array),C语言术语,也简称VLA。是指用整型变量或表达式声明或定义的数组,而不是说数组的长度会随时变化,变长数组在其生存期内的长度同样是固定的

我们来看看这一小段代码:

image.gif编辑

为什么编译不通过?原因在于:数组创建,在C99标准之前, [] 中要给一个常量才可以,不能使用变量。在C99标准支持了变长数 组的概念。这也说明了,当前编译器VS2019不属于C99标准。但是在其他一些编译器上是支持的!

初始化🍁

数组的初始化:数组的初始化是指,在创建数组的同时给数组的内容一些合理初始值(初始化)

数组在创建的时候如果想不指定数组的确定的大小就得初始化。数组的元素个数根据初始化的内容来确定。看下面的代码:

image.gif编辑

这里我们来看看一个经典的问题:下面的代码区分,内存中如何分配

image.gif编辑

我们不妨打开调试,打开监视,看看此时arr1和arr2里面的内容是什么:

image.gif编辑

在这里我们先来看看值,arr1中其实除了abc之外,还有\0,那这个\0在用sizeof计算大小的时候有没有算入呢?简单测试一下:

image.gif编辑

答案是有的!

使用🍁

对于数组的使用我们引入了一个操作符: [] ,下标引用操作符。它其实就数组访问的操作符。 我们来看代码:

image.gif编辑

我们要知道:数组是使用下标来访问的,下标是从0开始。数组的大小可以通过计算得到。可以通过sizeof来计算👇

越界问题🍁

数组的下标是有范围限制的。 数组的下规定是从0开始的,如果数组有n个元素,最后一个元素的下标就是n-1。 所以数组的下标如果小于0,或者大于n-1,就是数组越界访问了,超出了数组合法空间的访问。 C语言本身是不做数组下标的越界检查,编译器也不一定报错,但是编译器不报错,并不意味着程序就 是正确的, 所以程序员写代码时,最好自己做越界的检查。

我们稍微改变一下上面的代码,这也是许多初学者容易犯错误的地方,下面我们来看看这张图,里面标注了我想说的东西

image.gif编辑

与上面代码不同的地方在于i<=10!!!!大家留意一下🍭

我要提醒大家的是:在有些情况下,发生数组越界并不会报错,恰恰相反,它还会给你打印出结果来,到底是怎么一回事呢?我们通过一道题看一下究竟是怎么回事:

image.gif编辑

在这里,可怕的是编译器并没有报错,它还随机打印出一个值出来,对于数组越界的问题我们一定要多加注意啊!

同时,对于二维数组来说,二维数组的行和列也可能存在越界。

在内存中的存储🍁

不知道你有没有想过数组在内存中是怎么存储的?数组其实是顺序表,它其实在物理上和逻辑上是连续的,怎么去理解呢⁉️

我们可以通过创建一个数组,然后打印出地址,看看代码及其运行图:

image.gif编辑

我们知道int是4个字节,也就是相邻的元素之间差距4个字节4️⃣

同时,我们仔细观看结果,我们不难发现:随着数组下标的增长,元素的地址,也在有规律的递增。 由此可以得出结论:数组在内存中是连续存放的。这样就是我一开始所说的问题。大家好好想想。💡

好啦,到达这里,我们初步建立起了对一维数组的认识,现在基于一维数组的知识上,我们来看看二维数组⏬


拓展:sizeof和strlen()的区别🍁

关于这两个,我发现好多人老是弄混,所以在这里,给大家补充补充把:

sizeof

sizeof是一个操作符,是用来计算变量(类型)所占内存空间的大小,不关注内存中存放的具体内容,单位是字节

strlen

strlen是一个库函数,是专门求字符串长度的,只能针对字符串从参数给定的地址向后一直找\0,统计\0之前出现的字符的个数,strlen是计算的空间中字符的个数(不包括‘\0’)。

怎么理解sizeof是一个操作符?✅

image.gif编辑

很简单,我们可以看到。sizeof就算是不使用()也可以使用,这不难理解为什么说sizeof是一个操作符了!🆗


二维数组⭐️

二维数组本质上是以数组作为数组元素的数组,即“数组的数组”,类型说明符 数组名 [常量表达式] [常量表达式]。 二维数组又称为矩阵,行列数相等的矩阵称为方阵。

可千万不要以为二维数组是什么高大上的东西,本质上也只是数组而已。可别到后面看到矩阵就晕了,不知道矩阵是什么,其实用二维数组就是矩阵。

二维数组的创建🍁

image.gif编辑

我们同样可以根据不同类型创建不同的二维数组出来。第一个[]为行,第二个[]为列,比如第一个arr就是3行4列

初始化🍁

image.gif编辑

我们可以在创建的过程中就对其赋值,完成初始化,通过调试监视窗口,让我们来看看此时数组内容是什么:

image.gif编辑

我们可以知道:1.在初始化的过程中,里面的元素如果没有{}的话,就会直接默认放在第一行,第一行不够放的时候,会进入第二行,以此类推。

2.元素不够的时候,会自动初始化为0!

下面我们来看看二维数组是怎么使用的⏬

使用🍁

我们需要明确一点的就是:二维数组的使用也是通过下标的方式。

好啦,接下来基于一维数组的理解上,二维数组的使用对于我们并不是什么难事了,直接来看看我们的代码练习一下:

image.gif编辑

我们可以看到打印出来的结果只有一行,这时候可能有人会问了,怎么打印出类似矩阵的效果呢?好的,下面为你解答

image.gif编辑

我们只要每行(外层循环i)打印结束后加个换行就行了,这时候,你可能又会问:怎么让打印结果好看一些呢?作为一个有些强迫症的我继续为你解答!!!

image.gif编辑

看,这样打印出来的效果是不是好多了,区别在于%-2d,向左边对齐,如果是%2d就是向右边对齐,这里我就不演示了,可以自己去试一试。

下面,我们来看看二维数组是怎么存储的

在内存中的存储🍁

像一维数组一样,这里我们尝试打印二维数组的每个元素的地址

image.gif编辑

从运行结果来看,通过结果我们可以分析到,其实二维数组在内存中也是连续存储的。根据类型的不同会决定差距多少

好,抛开数组的基本知识意外,我们还会说到数组作为参数是怎么使用的


数组作为函数参数⭐️

错误的冒泡排序🍁

往往我们在写代码的时候,会将数组作为参数传个函数,这里以实现一个冒泡排序函数为例子引入数组作为函数参数是怎么一回事:

冒泡排序:

    1. 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
    2. 对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
    3. 针对所有的元素重复以上的步骤,除了最后一个。
    4. 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较

    其实冒泡排序就两个核心:1.两层for循环2.交换

    下面我们来模拟实现冒泡排序

    image.gif编辑

    是不是觉得代码没毛病?❌

    我可以负责任很明确的告诉你,上面代码出错了,为什么?

    image.gif编辑

    没有达到我们预期的效果。这时候怎么办,调试

    image.gif编辑

    请注意,这时候的sz并不是我们想要的结果,怎么变成1了呢?难道数组作为函数参数的时候,不是把整个数组的传递过去?

    好啦,到这里,我们先搁置一下这个问题,给大家先结束数组名是什么,通过介绍完数组名之后,你就会知道为什么会出现这种情况了

    数组名🍁

    我们来看看数组名的地址和第一个元素的地址有什么联系🔭

    image.gif编辑

    我们可以得出一个结论:

    数组名是数组首元素的地址。如果数组名是首元素地址,那怎么去理解这个呢?

    image.gif编辑

    结果是40,为什么呢?别急,凡事都有例外:数组名是数组首元素的地址。(有两个例外)📝

    1.sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小,单位是字节.通过它我们可以计算数组的元素个数

    2.&数组名,这里的数组名表示整个数组,取出的是整个数组的地址

    怎么去理解第二点呢?给你一个代码你就能理解搞定了:

    image.gif编辑

    可以看到&arr[0]+1走了4个字节,而&arr+1走了整个数组12个字节。所以说&arr取的是整个数组的地址!!💡

    好啦,基于以上的知识,我们回头看看我们刚开始的代码,通过一张图,给你指出为什么sz是1:

    image.gif编辑

    好啦,基于此,那我们要怎么去改进冒泡排序呢?🔈

    正确的冒泡排序🍁

    image.gif编辑

    传参数的时候直接把大小一起传过去就避免了错误的情况,OK,到这里,我们的冒泡排序总算是大功告成啦!🎉


    结束语😄

    好啦,通过上面的介绍,相信你对数组有了更加深刻的理解。到了这里,也是我们该说再见的时候了,本篇博客的内容也到了这里结束,如果觉得写得不错的话,记得给个赞呗,你们的支持是我创作的最大动力🌹


    目录
    打赏
    0
    0
    0
    0
    1
    分享
    相关文章
    一文彻底搞明白C语言的数组
    本文详细介绍了C语言中的数组,包括定义、初始化(静态与动态)、存储方式、访问方法及常用操作,如遍历、修改元素和作为函数参数传递。数组是C语言中最基本的数据结构之一,掌握它对编程至关重要。下篇将介绍二维数组,敬请期待!
    17 0
    一文彻底搞明白C语言的数组
    【C语言】两个数组比较详解
    比较两个数组在C语言中有多种实现方法,选择合适的方法取决于具体的应用场景和性能要求。从逐元素比较到使用`memcmp`函数,再到指针优化,每种方法都有其优点和适用范围。在嵌入式系统中,考虑性能和资源限制尤为重要。通过合理选择和优化,可以有效提高程序的运行效率和可靠性。
    214 6
    在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
    在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
    104 5
    C 语言数组与指针的深度剖析与应用
    在C语言中,数组与指针是核心概念,二者既独立又紧密相连。数组是在连续内存中存储相同类型数据的结构,而指针则存储内存地址,二者结合可在数据处理、函数传参等方面发挥巨大作用。掌握它们的特性和关系,对于优化程序性能、灵活处理数据结构至关重要。
    在C语言中指针数组和数组指针在动态内存分配中的应用
    在C语言中,指针数组和数组指针均可用于动态内存分配。指针数组是数组的每个元素都是指针,可用于指向多个动态分配的内存块;数组指针则指向一个数组,可动态分配和管理大型数据结构。两者结合使用,灵活高效地管理内存。
    C 语言中指针数组与数组指针的辨析与应用
    在C语言中,指针数组和数组指针是两个容易混淆但用途不同的概念。指针数组是一个数组,其元素是指针类型;而数组指针是指向数组的指针。两者在声明、使用及内存布局上各有特点,正确理解它们有助于更高效地编程。
    数据结构实验之C 语言的函数数组指针结构体知识
    本实验旨在复习C语言中的函数、数组、指针、结构体与共用体等核心概念,并通过具体编程任务加深理解。任务包括输出100以内所有素数、逆序排列一维数组、查找二维数组中的鞍点、利用指针输出二维数组元素,以及使用结构体和共用体处理教师与学生信息。每个任务不仅强化了基本语法的应用,还涉及到了算法逻辑的设计与优化。实验结果显示,学生能够有效掌握并运用这些知识完成指定任务。
    85 4
    【c语言】数组
    本文介绍了数组的基本概念及一维和二维数组的创建、初始化、使用方法及其在内存中的存储形式。一维数组通过下标访问元素,支持初始化和动态输入输出。二维数组则通过行和列的下标访问元素,同样支持初始化和动态输入输出。此外,还简要介绍了C99标准中的变长数组,允许在运行时根据变量创建数组,但不能初始化。
    85 6
    C语言:数组的分类
    C语言中的数组分为一维数组、多维数组和字符串数组。一维数组是最基本的形式,用于存储一系列相同类型的元素;多维数组则可以看作是一维数组的数组,常用于矩阵运算等场景;字符串数组则是以字符为元素的一维数组,专门用于处理文本数据。
    181 9
    C语言:什么是指针数组,它有什么用
    指针数组是C语言中一种特殊的数据结构,每个元素都是一个指针。它用于存储多个内存地址,方便对多个变量或数组进行操作,常用于字符串处理、动态内存分配等场景。
    AI助理

    你好,我是AI助理

    可以解答问题、推荐解决方案等