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

【C语言】数组

目录

一、数组的基本概念

1.1、什么是数组

1.2、数组的分类

二、一维数组

2.1、一维数组的创建

2.2、一维数组的初始化

2.3、一维数组的数据类型

2.4、访问一维数组的元素

2.5、一维数组在内存中的存储

2.6、用sizeof计算数组的长度

三、二维数组

3.1、二维数组是什么样的

3.2、二维数组的创建

3.3、二维数组的初始化

3.4、访问二维数组的元素

3.5、二维数组在内存中的存储

四、C99中的变长数组


一、数组的基本概念

1.1、什么是数组

        数组就是一个同一类型数据的集合。数组里面的数据叫元素,元素可以只有1个也可以有很多个,但是不能没有。

1.2、数组的分类

        数组分为一维数组和多维数组,多维数组常用的是二维数组,更高维的就很少见了。所以本文章主要讲解一维数组和二维数组。

二、一维数组

2.1、一维数组的创建

        创建一维数组的语法形式如下:

类型 变量名[常量值];举例:int arr[10];

        类型定义了数组存放的元素的数据类型;常量值定义了数组中元素的个数,决定了数组的长度。

2.2、一维数组的初始化

        数组使用大括号进行初始化,如下面的例子:

// 完全的初始化
int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};//不完全的初始化,未初始化的部分默认为0
int arr[10] = {1, 2, 3};//将所有元素都初始化为0,只初始化第一个,剩下的是默认值
int arr[10] = {0}//错误的例子--初始化的长度不能超过数组的长度
int arr[3] = {1, 2, 3, 4}

        字符类型的元素默认值也是0,因为十进制ASCII码0对应的字符就是\0。当一维数组初始化后,创建数组时中的常量值可以省略,它会根据初始化的元素个数自动计算数组的长度。验证如下:

        从上面的VS监视窗口中可以清晰地观察到数组的变化,大家可以试试Dve C++,观察起来根本不方便,不会把数组元素一个个这样列出来,所以在之前的文章说不建议新手使用Dev C++。

2.3、一维数组的数据类型

        大家想一想,对于整数的创建 int a; ,a是变量名,int 是 它的数据类型;那么对于数组 int arr[10];,就是 arr 是变量名,int [10] 是数组的数据类型。 不要把元素的数据类型跟数组的数据类型搞混了!!!

2.4、访问一维数组的元素

        如果一个一维数组的元素有n个,那么它的下标范围就是0~n-1,下标就相当于数组的索引一样,如下图例子:

        数组arr的长度为6,下标范围是0~5。访问数组的元素可以使用下标引用操作符:[]。比如想访问arr的第3个元素,就可以用a[2],a和2是[]的操作数。这样就能对素数的元素进行取值和存放了。对整个数据的元素进行访问,可以使用循环来实现。注意,使用scanf的时候,arr表示数组的起始地址,不用加取地址符&;但是arr[2]是一个数据,而不是地址,所以要加上&。

2.5、一维数组在内存中的存储

        一维数组在内存中是连续存放的,下面的代码可以验证这个结论:

        在x64环境下,地址的长度为64位;在x86环境下,地址的长度为32位。地址是用16进制的形式编码的。内存被分为了一个个的单元,每一个单元的存储容量是1字节。一个int类型的元素的长度为4字节,所以存放在4个单元中。

        上图中%p表示地址,可以看到打印出的结果,每相邻的两个元素的地址相差4个字节,证明了数组在内存中是连续存放的。

2.6、用sizeof计算数组的长度

       当需要把 arr[常量值] 中的常量值频繁改动时,for循环打印数组中用于判断的表达式也要跟着改动,甚至所有与这个常量值有关的语句都要一个个改动。这样太麻烦了,我们可以使用sizeof函数计算常量值来解决这个频繁改动的麻烦,如下:

        这样只需要改动创建数组时的常量值就行了。

三、二维数组

3.1、二维数组是什么样的

        如果把一维数组当作一个数组元素,那么这种数组元素组成的数组就是二维数组,二维以上的数组以此类推。下面用形象的图画表达二维数组是什么样的:

        图中的每一行就代表一个一维数组,框框边边的数字是二维数组的下标。

3.2、二维数组的创建

        二维数组的创建语法形式如下:

类型 变量名[常量值1][常量值2]举例:int arr[3][5];

        常量值1表示数组的行,常量值2表示数组的列。

3.3、二维数组的初始化

        二维数组的初始化也用大括号

//完全的初始化
int arr[2][3] = {1, 2 ,3 ,4 ,5 ,6};//不完全的初始化,剩下未初始化的默认为0
int arr[2][3] = {1, 2, 3, 4};

        int arr[2][3] = {1, 2, 3, 4}; 用图形表现:

        可以发现是一行一行放满,再放下一行。

        二维数组也可以不一行一行放满,按照行初始化

int arr[2][3] = {{1, 2}, {3, 4}};

        也可以省略常数值1表示的,但不能省略常数值2表示的列:

int arr[][3] = {1, 2, 3, 4, 5, 6, 7};

        如果列也省略了,那就完全不知道数组是按照什么顺序放的了。比如上图这个例子有7个数,数组可以是:1*7、2*4、3*3的大小,就不知道是选哪种。

3.4、访问二维数组的元素

        二维数组的行和列的下标都是以0开始的。

int arr[2][3] = {1 ,2 , 3, 4, 5, 6};访问元素5可以使用arr[1][1]

        如果想访问整个数组的元素,可以使用两层循环,分别遍历行和列。

3.5、二维数组在内存中的存储

        二维数组在内存中也是连续存放的,下面的代码可以验证:

        可以从运行结果看到每一个元素的起始地址之间相差4个字节。虽然用下标访问元素或者画图的时候是用的二维的形式表现,这样是为了人能更好理解,但实际上二维数组在内存中的存放是“一维的”。

四、C99中的变长数组

        首先科普一下C99是什么:C语言有国际的标准,这个标准随着优化、扩展会进行更新,这些历代更新的版本就叫C89、C90、C98、C99、....、C11、C17、C23等等。但是我们现在常用的还是老版的C89和C90,像之后的C99都没有普及。因此在VS在默认下是不支持变长数组的,可以看看下边的代码:

        在OJ网站上刷题、Dev C++集成开发环境上是支持变长数组的。使用变长数组的时候要注意,变长数组不能初始化;变长是指数组的长度可以是变量,而不是指数组的长度可以变化!!!一旦创建了数组,就不能更改数组的长度了。

        VS默认下是使用微软的MSVC编译器,我们改成使用苹果的Clang编译器就支持C99标准了。修改方法如下:

        快捷键 windows + s 弹出搜索框,找到 Visual Studio Installer 并运行,点击修改。

        在C++开发下找到Clang并勾选,完成修改,等待下载(下载时间比较长)。

        打开你的项目,在解决方案目录下的项目名处,右击属性 >> 常规 >> 平台工具集

        选择 LLVM(clang-cl)>> 应用,就能使用变长数组了。如果不想用了,也可以用同样的方式改回编译工具。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • K-近邻和神经网络
  • 结合python+redis+mysql制作镜像
  • Aippt产品运行逻辑分析
  • Linux 面试准备 - 2024
  • 传统放牧方式与北斗科技的碰撞:北三短报文头羊定位追踪器PD28守护放牧生活
  • 【根据字符出现频率排序】python刷题记录
  • 阿里云RDS到亚马逊云RDS的实时数据同步方案详解
  • 传知代码-智慧医疗:纹理特征VS卷积特征(论文复现)
  • VSCode切换默认终端
  • IP Fabric三层路由
  • 关于黑马Ajax项目的笔记
  • 原生微信小程序wxml2canvas生成海报并包保存至本地
  • 【网络安全】文件上传基础及过滤方式
  • Vue前端工程
  • 【面试】前端开发中的“八股文”:助力还是阻力?
  • 《深入 React 技术栈》
  • chrome扩展demo1-小时钟
  • IP路由与转发
  • Java程序员幽默爆笑锦集
  • Java深入 - 深入理解Java集合
  • PHP那些事儿
  • WebSocket使用
  • 彻底搞懂浏览器Event-loop
  • 从setTimeout-setInterval看JS线程
  • 工程优化暨babel升级小记
  • 观察者模式实现非直接耦合
  • 基于 Babel 的 npm 包最小化设置
  • 经典排序算法及其 Java 实现
  • 问题之ssh中Host key verification failed的解决
  • 用Python写一份独特的元宵节祝福
  • Android开发者必备:推荐一款助力开发的开源APP
  • C# - 为值类型重定义相等性
  • HanLP分词命名实体提取详解
  • # 20155222 2016-2017-2 《Java程序设计》第5周学习总结
  • # 执行时间 统计mysql_一文说尽 MySQL 优化原理
  • (CVPRW,2024)可学习的提示:遥感领域小样本语义分割
  • (delphi11最新学习资料) Object Pascal 学习笔记---第13章第6节 (嵌套的Finally代码块)
  • (pytorch进阶之路)CLIP模型 实现图像多模态检索任务
  • (安全基本功)磁盘MBR,分区表,活动分区,引导扇区。。。详解与区别
  • (博弈 sg入门)kiki's game -- hdu -- 2147
  • (附源码)spring boot建达集团公司平台 毕业设计 141538
  • (附源码)ssm考生评分系统 毕业设计 071114
  • (附源码)计算机毕业设计ssm电影分享网站
  • (官网安装) 基于CentOS 7安装MangoDB和MangoDB Shell
  • (介绍与使用)物联网NodeMCUESP8266(ESP-12F)连接新版onenet mqtt协议实现上传数据(温湿度)和下发指令(控制LED灯)
  • (十八)Flink CEP 详解
  • (四)模仿学习-完成后台管理页面查询
  • (转载)PyTorch代码规范最佳实践和样式指南
  • . NET自动找可写目录
  • .locked1、locked勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复
  • .NET Micro Framework初体验
  • .net 生成二级域名
  • .NET 应用架构指导 V2 学习笔记(一) 软件架构的关键原则
  • .NET中winform传递参数至Url并获得返回值或文件
  • @transaction 提交事务_【读源码】剖析TCCTransaction事务提交实现细节