批量组织相同数据类型的基础数据结构——数组

批量组织相同数据类型——数组

  • C语言将数组看作派生类型(建立在其他类型的基础上)
  • []:变地址运算符,表示将指针移动多少个存储单元。如a[n]=a[0]+n*sizeof(a[0]);
  • 数组的索引,即为下标(变地址运算符中的偏移量)。数组索引范围: [ 0 , 数组大小 − 1 ] [0,数组大小-1] [0,数组大小1]。数组越界(索引超出范围,索引为负数等)是未定义行为(访问了未经申请的内存)。
  • C99之后增加了变长数组(VLA),允许用变量表示数组的维度(包括用const修饰符限定的变量)。注意,VLA并非在运行时可以自动改变数组大小。VLA必须为自动(auto)存储类别,不能为static或extern,且不能在声明时进行初始化。
  • 数组的初始化分为完全初始化与不完全初始化。对于非字符数组类型,初始化数组采用序列表的方式(即为{}的形式),序列表仅允许在初始化时使用。对于不完全初始化,编译器会将未初始化的部分设为0。如果在块作用域中没有初始化数组且为自动数组(auto),会被填充随机值,一般将随机值视为垃圾数据。
  • 指定初始化器:可以在初始化列表中指定待初始化的元素。例:int arr[6]={[5]=0};指定初始化器的用法可以与普通初始化的方法混用。例:int a[6]={1,[3]=5,6,7};中,由于中间使用逗号运算符进行分隔,故执行顺序为从左到右依次进行,a[0]=1,a[3]=5,a[4]=6,a[5]=7;其余为0。若对同一元素出现了多次修改,则以最后面的作为最终结果(逗号运算符特性,后面的会覆盖前面的)。这种下标继承方式类似于枚举中的用法。
    注:指定初始化器的方式进行初始化为C99的扩展,标准C++不支持这种写法,具体实现取决于C++编译器(g++不允许,clang++允许)。
  • 求数组长度:(sizeof(数组名)/sizeof(数组名[0]))(再次注意:sizeof是标识符而非函数)
  • 常量数组:加上const修饰符的数组,一旦创建之后,数组将为只读,内容不可被修改。
  • 不允许直接将一个数组通过赋值表达式给其他数组。
  • 数组名:即为整个数组的地址,同时也是数组中首元素的地址(即数组的基址)。
  • 基址是指用于定位数据结构中元素位置的地址。它通常指向数据结构的起始位置或者某个特定元素的位置。基址通常与偏移量结合使用,通过基址加上偏移量来计算访问数据结构中的特定元素的内存地址。

    在数组中,基址指的是数组的起始地址,即数组的首元素的地址。数组名在大多数情况下可以被视为数组的基址,通过数组名可以访问数组中的元素,时间复杂度为 O ( 1 ) O(1) O(1)。因此,数组中变地址运算符可视为数组的偏移量。

    在函数调用中,基址指的是当前函数栈帧的基址,也就是栈帧中局部变量和参数的起始地址。基址指针在函数调用过程中用于帮助定位局部变量和参数。

    总的来说,基址是用于定位数据结构中元素位置的地址,它是访问数据结构中元素的起点。

  • 数组是一种顺序表,在内存中存储是连续的

多维数组

以最简单的多维数组——二维数组举例:

C语言遵循高维度优先原则,在二维数组中体现为行优先原则。二维数组的初始化,为避免混淆,一般采用嵌套序列表的方式进行(但并不绝对)。

int a[6][4];//定义了一个6行4列的二维数组

二维数组是若干个一位数组的数组,二维数组的每一个元素都是一维数组。对于上述二维数组a,其本身是一个有6个元素的一维数组(a[3])称为主数组。主数组中的每个元素是包含4个元素的一维数组。

注意:数组是顺序表,在内存中始终是顺序存储的,行和列只是为了方便理解而创造出来的,在内存中存储并不涉及行和列的概念。

从指针角度看二维数组:

  • 数组名a是整个主数组a的地址,也是主数组中首元素a[0]的地址,a[0]是大小4个int的数组,因此a是占有4个int大小对象的地址。
  • a[0]元素本身是一个数组,因此a[0]是a[0]中首元素a[0][0]的地址,因此a[0]是占用1个Int大小对象的地址。
  • 一句话总结:a=&a[0],a[0]=&a[0][0];*a=*(&a[0])=a[0]=&a[0][0],**a=*a[0]=*(&a[0][0])=a[0][0]
  • 以上地址的地址(二级地址)、指针的指针(二级指针),是双重间接

例:

a+1//a=&a[0],a[0]是4个int大小的数组,因此a+1为+4个int大小,即为行指针下移,变为a[1]
a[0]+1//a[0]=&a[0][0],列指针下移,变为a[0][1]
(a+1)[2]//a=&a[0],行指针下移1个存储单元,变为a[1],之后通过变地址运算符行指针再下移2行,变为a[3]
(a[0]+1)[2]//a[0]=&a[0][0],列指针下移1个存储单元,变为a[0][1],之后通过变地址运算符列指针再右移2个存储单元。再次注意:数组是顺序表,在内存中存储是连续的,因此可跨行移动
(a+1)[0][2]//a=&a[0],行指针下移1个存储单元变为a[1],之后通过变地址运算符转换为列状态,列指针再下移2个存储单元

从存储单元角度理解,会发现容易很多。

  • 二维数组在函数定义中做函数形参时,行可以缺省,但列不能缺省。即使行未缺省,编译器也会自动忽略该值。对于多维数组来说,在函数定义中做形参时,只能省略最左侧方括号中的值。(因为最左侧方括号表明其为一个指针)。
  • VLA的二维数组在函数声明时若要省略维度形参,必须用*来代替省略的维度。在函数定义时则只能缺省最左侧的维度形参,其余维度形参在函数形参表中必须比数组先进行声明。(注意形参永远只能被看作是声明而非定义,因为形参只发生在函数调用时而非函数定义时)

指针数组

注意优先级[]>*

int *p[2];//定义了大小为2的数组,每个元素都是int*(int型指针)
//其实应该相当于:
int* p[2];

数组指针

注意优先级[]>*

int (*p)[2];//定义了一个可以指向含有2个int型元素的一维数组的指针

在二维数组中应用数组指针则相当于行指针。

以上内容可以用指针函数和函数指针数组理解

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/686549.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

.NET Core WebAPI中使用swagger版本控制,添加注释

一、效果 二、实现步骤 在代码中添加注释 在项目属性中生成API文档 在Program中注册Swagger服务并配置文档信息 // 添加swagger注释 builder.Services.AddSwaggerGen(x > {x.SwaggerDoc("v1", new OpenApiInfo { Title "Swagger标题", Version "…

MongoDB从入门到实战之.NET Core使用MongoDB开发ToDoList系统(2)-Swagger框架集成

Swagger是什么? Swagger是一个规范且完整API文档管理框架,可以用于生成、描述和调用可视化的RESTful风格的 Web 服务。Swagger 的目标是对 REST API 定义一个标准且和语言无关的接口,可以让人和计算机拥有无须访问源码、文档或网络流量监测就…

前端秘法进阶篇----这还是我们熟悉的浏览器吗?(浏览器的渲染原理)

目录 一.浏览器渲染原理 二.渲染时间点 三.渲染流水线 1.解析html(Parse HTML) 1.1解析成DOM树(document object model) 1.2解析成CSSOM树(css object model) 2.样式计算(Recalculate Style) 3.布局(Layout) 4.分层(Layer) 5. 绘制(Paint) 6.分块(Tiling) 7. 光栅化…

partial的使用举例

functools模块中的partial函数用于部分应用(partial application)一个函数的参数,即固定函数的部分参数,从而返回一个新的函数。 下面是一个使用partial函数的示例: python from functools import partial # 定义一…

360可视门铃双摄版恢复案例

家用的智能摄像头恢复了很多,但是可视门铃的恢复却是第一次,现代社会似乎已经全方位处于监控网络之下。360的产品很多,可视门铃只是其众多品牌中的一个,这个案例能让我们窥视到360的开发小精产品的理念。 故障存储: 64G TF卡/ex…

python入门:常用模块—shutil 模块

高级的 文件、文件夹、压缩包 处理模块 shutil.copyfileobj(fsrc, fdst[, length]) 将文件内容拷贝到另一个文件中 1 2 mport shutil shutil.copyfileobj(open(old), open(new, w)) shutil.copyfile(src, dst) 拷贝文件 1 shutil.copyfile(f1.log, f2.log) # 拷贝文件&…

时序预测 | Matlab实现BO-LSSVM贝叶斯算法优化最小二乘支持向量机时间序列预测

时序预测 | Matlab实现BO-LSSVM贝叶斯算法优化最小二乘支持向量机时间序列预测 目录 时序预测 | Matlab实现BO-LSSVM贝叶斯算法优化最小二乘支持向量机时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 Matlab实现BO-LSSVM贝叶斯算法优化最小二乘支持向量机时间…

函数、极限、连续——刷题(5

目录 1.题目:2.解题思路和步骤:3.总结:小结: 1.题目: 2.解题思路和步骤: 首先可能想到的是答案为0,但是不可以把 直接化简为n 这里要用到分子分母的平方差,sin^2的周期为π&#x…

计算机网络——14CDN

CDN 视频流化服务和CDN:上下文 视频流量:占据着互连网大部分的带宽 Netflix,YouTube:占据37%,16%的下行流量 挑战:规模性-如何服务~1B用户? 单个超级服务器无法提供服务(为什么&am…

函数、极限、连续——刷题(4

目录 1.题目:2.解题思路和步骤:3.总结:小结: 1.题目: 2.解题思路和步骤: 记住这个公式即可: 所以就很容易求解了: 3.总结: 记住这个公式即可: 小结&am…

祝所有的CSDN社区成员们新年快乐

文章目录 尊敬的CSDN社区成员们, 在新年的钟声即将敲响之际,我携带着满心祝福与期许,以字为舟,穿越虚拟与现实的界限,来到您的身边,向每一位热爱编程、投身技术研究、在CSDN平台上挥洒智慧和汗水的朋友们&a…

如何使用iptables或者firewalld配置Linux系统的防火墙策略

在网络安全中,防火墙是一种关键的安全设备,用于保护计算机网络免受恶意攻击和未经授权的访问。在Linux系统中,我们可以使用iptables或者firewalld来配置防火墙策略。本文将介绍如何使用这两种工具来配置Linux系统的防火墙策略,包括…

Spring Cloud Hystrix:服务容错与熔断

1. 理解服务容错与熔断 1.1 服务容错的概念和重要性 在分布式系统中,由于各种原因(例如网络延迟、服务故障等),服务之间的通信可能会出现故障或者延迟。为了提高系统的可用性和稳定性,需要实现服务容错机制&#xff…

数据结构:4_二叉树

二叉树 一.树概念及结构 1. 树的概念 树是一种非线性的数据结构,它是由n(n>0)个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。 有一个**特殊的…

17.3.1.6 自定义处理

版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的。 模拟某款图像处理软件的处理,它只留下红色、绿色或者蓝色这样的单一颜色。 首先按照颜色划分了6个色系,分别…

基于Arduino UNO设计一个温控制系统

目录 概述 1 硬件结构 1.1 整体硬件介绍 1.2 硬件连接结构 2 软件设计 2.1 软件功能介绍 2.2 关于Arduino的一些知识点 2.2.1 定时器 2.2.2 PWM 2.3 代码实现 2.3.1 编译工具 2.3.2 详细代码 3 测试 3.1 温度数据监控 3.2 温控测试 概述 本文介绍如何使用Ardui…

Rust 语言学习杂谈 (end) (各种工作中遇到的疑难杂症)

1.在运行 “cargo build --release” 的时候,到底发生了什么? 源 (GPT4.0) : 当我们运行 cargo build --release 命令时,实际上在进行一系列复杂的步骤来编译和构建 Rust 项目的发布版本。这个过程大致可以分解为以下几个步骤:…

MCU电源控制(PWR)与低功耗

目录 一、STM32 的内核和外设电源系统管理: 二、MCU电源监控: 三、三种低功耗模式: 1、睡眠模式: 2、停止模式: 3、待机模式: 一、STM32 的内核和外设电源系统管理: ① 电池备份区域&#…

关于预训练模型的一点感悟

最近,Yann LeCun 在 WGS 上说: 目前的LLM不可能走到AGI,原因很简单,现在训练这些LLM所使用的数据量为10万亿个令牌,也就是130亿个词,如果你计算人类阅读这些数据需要多长时间,一个人每天阅读8小…

String讲解

文章目录 String类的重要性常用的方法常用的构造方法String类的比较字符串的查找转化数字转化为字符串字符串转数字 字符串替换字符串的不可变性 字符串拆分字符串截取字符串修改 StringBuilder和StringBuffer String类的重要性 在c/c的学习中我们接触到了字符串,但…