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

数组——初识数据结构

一维数组

数组的创建

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

数组的创建方式

C99 中引入了变长数组的概念,变长数组支持数组的大小使用变量来指定

明显这里的vs2019不支持变长数组

数组初始化和不完全初始化

第二个数组就是典型的不完全初始化,开辟了10个空间,只有第一个是1,剩下的就用0填充

这里的ch1和ch2看起来似乎一样,但ch1只有 a b c, 后面的0是编译器主动加上的;ch2是abc\0,\0的ASCII码值也是0,所以后面也是6个0,但ch2本身就自带了一个

这样的代码也是有问题的,这里只用了一个空字符串初始化,所以数组的长度是一个元素

一维数组的使用

一个数组初始化好后每个元素都有其下标,下标是从0开始的

一维数组在内存中的存储

这里我们打印一下数组的每个元素的地址看看,%p是打印地址

我们发现每个相邻的地址最后的数字就相差4,因为这是整形数组,而一个整型是4个字节

数组在内存重视连续存放的!

随着数组下标的增长,地址也是由低到高变化的

数组开辟的空间也不宜太大

数组中的数据放在栈区

0和\0

二维数组

二维数组的创建

初始化

第一个参数是行数,第二个是列数

这个数组是怎么存放的呢?

其实是1234先把第一行放满,5放在第二行,其余的位置都是0

还有另一种初始化方式

就是指定初始化位置

以及,对于二维数组,初始化时,可以省略行,不能省略列

二维数组的使用

我们尝试一下一列一列打印

二维数组在内存中的存储

试着打印一下地址看看

能发现他们似乎也是连续存放的

也能将它们理解为一个12元素的整型数组

数组越界

当我们访问的空间超过数组申请的空间时,就造成了越界访问

还有这样

可能有人比较疑惑,为啥5会打印两次呢?

第一次打印了5个,第二次还是从行的下标0位置处开始,5这个位置是数组第二行的第一个元素,所以还会被打印一次。

数组应用

冒泡排序

冒泡排序(Bubble Sort)是一种简单直观的排序算法

冒泡排序的核心思想是:

通过相邻元素两两比较,把较大的元素“冒泡”到序列的一端,像水中的气泡一样逐步上升。

具体过程如下:

  • 从头到尾依次比较相邻两个元素,如果前一个比后一个大,就交换它们;

  • 每完成一轮,最大的元素就被“冒泡”到了当前未排序部分的末尾;

  • 然后对剩下的部分重复这一过程,直到整个序列有序。

比如排序 [5, 2, 4, 3, 1],第一轮结束后变成 [2, 4, 3, 1, 5],最大值 5 被放到了最后。之后对 [2, 4, 3, 1] 再次进行“冒泡”,直到全部排好序。

设有一个长度为 n 的数组,共需进行最多 n-1 轮“冒泡”:

  • 第 1 轮:比较 n-1 次,把最大值移到末尾;

  • 第 2 轮:比较 n-2 次,把次大值移到倒数第二位;

  • n-1 轮:只需比较 1 次。

基本理念就是数组中的元素两两相比较,随后判断是否交换位置,最终的目的是排成一个升序或降序数组

或者函数的形式

#include<stdio.h>
void bubble_sort(int arr[10])
{//求数组的元素个数int sz = sizeof(arr) / sizeof(arr[10]);//冒泡排序的趟数int i = 0;for (i = 0; i < sz - 1; i++){//一趟冒泡排序int j = 0;for (j = 0; j < sz - 1 - i; j++){if (arr[j] > arr[j + 1]){int tmp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = tmp;}}}
}int main()
{int arr[10] = { 9,8,7,6,5,4,3,2,1,0 };int sz = sizeof(arr) / sizeof(arr[0]);//0 1 2 3 4 5 6 7 8 9//要对数组升序排序//冒泡排序bubble_sort(arr);//打印for (int i = 0; i < sz; i++){printf("%d ", arr[i]);}return 0;
}

但结果好像不对诶~

原来上面数组名传参的时候传递的只是数组首元素的地址,形参就是指针变量来接收,并没有把整个数组传上去。(这叫做数组名的降级)

上面sz就是1了,所以数组才会没变化

这时我们只需要在main函数里先把sz计算好,然后传给排序函数就行

#include<stdio.h>
void bubble_sort(int arr[10],int sz)
{//冒泡排序的趟数int i = 0;for (i = 0; i < sz - 1; i++){//一趟冒泡排序int j = 0;for (j = 0; j < sz - 1 - i; j++){if (arr[j] > arr[j + 1]){int tmp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = tmp;}}}
}int main()
{int arr[10] = { 9,8,7,6,5,4,3,2,1,0 };int sz = sizeof(arr) / sizeof(arr[0]);//0 1 2 3 4 5 6 7 8 9//要对数组升序排序//冒泡排序bubble_sort(arr,sizeof(arr)/sizeof(arr[0]));//打印for (int i = 0; i < sz; i++){printf("%d ", arr[i]);}return 0;
}

看一下这段代码

运行结果是两边都相等!

这里刚好也得出了

当p指向数组的第一个元素时,p+i就指向数组第i个元素

p里存放着数组首元素的地址,所以p和arr可以相互替换,下面这些效果也相等

还有加法交换律能得出的结论

前面讲了数组名是数组首元素地址,但存在两个例外

sizeof(数组名),数组名表示整个数组,计算的是整个数组的大小,单位是字节

&数组名,数组名表示整个数组,取出的是整个数组的地址

看看这个,前面两个+1后跳过了一个整型元素,地址都是+4,而第三个+1后跳过了整个数组,地址变化了40个字节

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

相关文章:

  • 算法第26天|贪心算法:用最少数量的箭引爆气球、无重叠区间、划分字母区间
  • 35.安卓逆向2-frida hook技术-过root检测
  • 元宇宙游戏与VR的关联性及发展分析(截至2025年7月)
  • 【Spring拦截器实战】路径拦截与访问控制系统设计
  • MybatisPlus入门指南
  • SonarQube 代码分析工具
  • docker 中安装 ONLYOFFICE 服务
  • C++基础学习——文件操作详解
  • netframe4.5 的mvc 框架 layui 组件的引用
  • 模运算常见定律
  • .net 警告【代码 CS1998】此异步方法缺少 “await“ 运算符,将以同步方式运行。
  • Linux命令集锦-个人整理(偏向进程和端口的查询)
  • CS231n-2017 Lecture5卷积神经网络笔记
  • 如何把jar包打成docker镜像(SpringBoot项目打包成Docker )部署到Linux
  • CMOS知识点 离子注入工艺
  • OpenCV Mat UMat GpuMat Matx HostMem InputArray等设计哲学
  • Arduino学习笔记【快速入门】
  • 蓝牙通信架构(Bluetooth/BLE)
  • Windows系统暂停更新工具
  • 每日面试题12:JVM垃圾回收机制
  • 分布式数据库中间件ShardingSphere
  • Unity UI的未来之路:从UGUI到UI Toolkit的架构演进与特性剖析(1)
  • Java学习-----Bean
  • Datawhale AI 夏令营-心理健康Agent开发学习-Task1
  • 猎板 PCB:多场景适配下印制线路板的材料选择优化策略
  • 朴素贝叶斯算法原理与案例解析
  • linux: tar解压之后属主和属组不是当前用户问题
  • 2025人形机器人动捕技术研讨会即将于7月31日盛大开启
  • 阿里巴巴视觉算法面试30问全景精解
  • 知识库搭建之Meilisearch‘s 搜索引擎-创建搜索引擎项目 测评-东方仙盟测评师