P22 C++数组

news2024/11/28 8:26:50

目录

前言

01 什么是数组

02 如何定义数组

2.1 那么如何设置和访问这些整数呢?

2.2 小心内存越界

2.3 for循环遍历数组

03 在堆上创建数组


前言

本期我们讨论 C++ 中的数组。

在我们开始讨论数组之前,要先理解指针是什么,因为指针基本上是 C++ 数组的工作方式的基础。

关于指针的博文P7 C++指针-CSDN博客

01 什么是数组

首先,什么是数组?

数组是元素的集合,是按特定的顺序排列的一堆东西。

在我们的下面的例子中,C++ 数组就是一堆的变量组成的集合,一般是一行相同类型的变量。

数组如此重要和有用的原因,是我们经常想要表示一大堆数据的数据集合。

对于我们来说,创建一大堆变量是没有意义的,这些数据应该放在一个数据集中,因为变量需要手动创建。

想象一下,我们需要在代码中指定变量并给它们命名,然而有时候我们只是想要能够存储 50 个整数代表某种数据,我们不想去详细说明整数1号,整数2号......,一直到整数50号。这太恐怖了,根本不可行,无法维护。要设置所有这些变量都等于0,你要写50行代码,然后手工将这些变量设置为0,处理这么多变量真的很麻烦。

在这种情况下,我们想做的是使用一个数组来包含所有的50个相同类型的元素,这样这些整数处理起来就轻松多了。

记住,数组就像在一个变量中有多个变量,我们给数组起一个名字,通过这个名字,我们可以创建数组,然后引用尽可能多的变量。

让我们在代码中看一下。

02 如何定义数组

定义数组非常的简单,假设我想要一个5个整数的数组。

#include <iostream>

int main()
{
    int arr[5];
    return 0;
}

写上想要的数组类型,然后给他一个名字叫做 arr,然后在中括号里放入我们想要引用的变量数量。

现在我们有一个有5个整数的数组,而且分配了足够的空间来存储5个整数。

2.1 那么如何设置和访问这些整数呢?

其实和C语言是一样的

可以写数组的名字,然后在方括号内写上 index(索引)。

索引用于在数组中指向一个变量或者元素。

第一个元素要写上0,因为在 C++ 中下标是从0开始的

#include <iostream>

int main()
{
    int arr[5];
    arr[0] = 0;   //设置变量
    arr[4] = 4;
    std::cout << arr[0] << std::endl; //访问变量
    std::cout << arr[4] << std::endl;
    return 0;
}

我们可以把索引设置成任何整数,因为它只是一个整数,example 是一个整型数组,当我们在一个特定的索引上访问这些元素之一时,我们得到这个元素的类型就是数组的类型。

你可能会注意到第一个索引是0,这意味着,最后一个索引应该是4而不是5。我们把最后一个设置4,其他的元素先不设置。

如果想打印某个变量,我们只需要指明索引就可以了,而如果你想打印这个数组,你需要打印这个数组的地址,它实际上是一个指针类型。当你索引数组中的元素时,你会得到底层的数据类型。

 当然,我可以创建一个新变量,然后将数组中的值复制给这个变量,你可以看到这里的数据类型只是一个普通的 int 类型。

2.2 小心内存越界

如果我试图访问一个索引,但是这个索引不在数组里面,例如访问 -1 或 5,我们称之为 Memory access violation (内存访问违规)。我在试图访问不属于我的内存。

在 debug 模式下,你会得到一个程序崩溃的错误消息。然而,如果在 release 模式下,你可能不会得到报错信息。

这意味着你已经写入了不属于你的内存。你要注意你是在数组的边界内写东西,这一点非常重要,因为如果你没有这样做,它会导致一些很难调试的问题,因为你刚刚修改了内存,这些内存不是这个数组的一部分,而是有可能是源代码中另一个变量的某一部分,你只是在没有意识的情况下,将代码中的其他变量改掉了,所以你要尽可能设置安全检查,确保你写的东西你没有超出界限。

2.3 for循环遍历数组

P5 C++循环(for,while)-CSDN博客

数组经常与 for 循环一起出现。因为 for 循环可以通过索引在一个特定的范围内来遍历。

如果我们想设置 arr数组中的每一个值,可以通过 for 循环实现,如果没有 for 循环,我们需要一个一个使用所有索引,并手动赋值。而通过创建一个 for 循环,遍历数组的整个长度,就很方便了。

当然,上面例子中的 for 循环的循环条件也可以写成 i <= 4,不过基本没有人会这样写,这涉及到性能问题,因为你在做小于以及等于的比较,所以它必须做等于比较,而不仅是做小于比较,耗费的时间较多。

我们在5行打个断点,Debug调试一下,看看内存中是什么样子的。

如果还不知知道怎么调试或者安装环境,可以看我主页的博文

Ubuntu 1.84.2Visual Studio Code 下载配置与vscode查看内存Hex Editor插件,简单易懂-CSDN博客

 ubuntu linux C/C++环境搭建-CSDN博客

arr 实际上就是它自己的内存地址,因为 arr是一个整型指针

开始的时候都是很乱的数字,因为还未进行初始化,所以里面的内容都是未知的

当我循环两次过后,则i = 1的时候,我们看一下数组的内存情况

循环完后
​​​​的内存情况

因为我的是Vs code,并不能直接看数组的地址,所以我定义了个指针,让指针指向arr数组

 可以看到数组最重要的一点是,它是连续的存储数据,它们的数据放在了一排。

我给5个整数分配了内存空间,这意味着我将它们一个接一个放进内存中。在内存中,每个整数是4个字节,所以在这里得到的是一行20字节的内存,他被分成几个4字节段(并不是真的分成了4字节段),当我们通过代码访问他时,可以理解为是被分段的。

在上面的内存视图中,我们可以看到5个2,每个占据4字节,因为它们是整型 int。

我们通过 arr[i] 来访问特定索引时,实际上是对这个内存取了一个偏移量,比如在索引2的地方,arr[2],它会从数组的开头开始,增加8个字节(因为每个整数有4个字节),我们想要访问元素2,就是索引从0开始之后的第三个元素。

简单一句话总结,索引是2的元素,地址偏移是 每个元素的大小*2,如果我们给这个位置赋一个值,会将数据写入到它所在的这部分内存中。

以上就是数组的基本原理了,他们只是一个连续的数据块,你可以像索引一本书一样索引它们,然后写在特定的页面。

我们还可以在堆上(heap)创建一个数组。

03 在堆上创建数组

我们可以通过 new 关键字来创造一个对象(实例),同样,我们也可以通过使用 new 来创建一个数组。

#include <iostream>

int main()
{
    int arr[5];
    int *parr = new int[5];
    return 0;
}

我们在上面的代码中创建了另一个数组 parr,类型是 int*,括号里面是数组的大小。这个代码和之前的代码其实是一个意思,不过它们的生存期是不一样的。

第五行的数组是在栈上创建的,程序运行到最后花括号时它会被销毁,因为跳出了作用域范围。

第六行的数组是在堆上创建的,这个直到我们程序把它销毁之前,它都是处于活动状态,所以你需要用 delete 关键字来删除,因为这是一个数组,我们在这里使用数组的操作符 [ ] 来分配内存,所以我们使用了带方括号的 new 关键字。对应的,我们也需要使用 [ ] 删除它。

    delete[] parr;

继续修改一下程序。

#include <iostream>

int main()
{
    int *parr = new int[5];
    for(int i = 0; i < 5; i++)
    {
        parr[i] = 2;
    }
    delete[] parr;
    return 0;
}

我们使用循环赋值,将数组的值都等于2。

打个断点来调试一下。

可以看到结果完全是相同的。

那么为什么要动态的用 new 来分配而不是在栈上创建呢?

主要原因是因为生存期。

用 new 来分配的内存,它将一直存在,直到你主动删除它

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

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

相关文章

快速开发表单好用吗?优势在哪?

如果应用快速开发表单&#xff0c;对提升企业的办公效率帮助巨大。在快节奏的现代社会生活中&#xff0c;职场办公也需要采用更专业的办公软件实现高效率提升。低代码技术平台就是如今常用于职场办公中的优质平台&#xff0c;其可视化操作、简单灵活、组件丰富等优势特点&#…

如何往excel中写子表?

with pd.ExcelWriter("C:/last_date.xlsx") as writer:for i in range(0, 10):df pd.DataFrame()df.to_excel(writer, indexFalse, sheet_namestr(days[i 1]))

【青蛙跳台阶问题 —— (三种算法)】

青蛙跳台阶问题 —— (三种算法&#xff09; 一.题目介绍1.1.题目1.2.图示 二.解题思路三.题解及其相关算法3.1.递归分治法3.2.动态规划算法&#xff08;Dynamic Programming&#xff09;3.3.斐波那契数列法 四.注意细节 一.题目介绍 1.1.题目 一只青蛙一次可以跳上1级台阶&am…

跨标签页通信的8种方式(上)

跨标签页通信是指在浏览器中的不同标签页之间进行数据传递和通信的过程。在传统的Web开发中&#xff0c;每个标签页都是相互独立的&#xff0c;无法直接共享数据。然而&#xff0c;有时候我们需要在不同的标签页之间进行数据共享或者实现一些协同操作&#xff0c;这就需要使用跨…

WhatsApp企业号如何增粉?5个客户开发技巧

收集粉丝关注的方法有很多种&#xff0c;本文将会介绍九种有效的方式&#xff0c;可以参考。 在传播信息的过程中&#xff0c;我们要需要把客户放在第一位&#xff0c;你能提供给客户什么&#xff0c;实用价值或情绪价格。给人的感觉真实吗&#xff1f;足够透明吗&#xff1f;…

爬虫系统Docker和Kubernetes部署运维最佳实践

在构建和管理爬虫系统时&#xff0c;使用Docker和Kubernetes可以带来诸多好处&#xff0c;如方便的部署、弹性伸缩和高可靠性。然而&#xff0c;正确的部署和运维实践对于确保系统稳定运行至关重要。在本文中&#xff0c;我将分享爬虫系统在Docker和Kubernetes上的最佳部署和运…

办公软件PDF转换工具 - pdftool

办公软件PDF转换工具 - pdftool&#xff0c;支持&#xff1a; 1、图片转PDF&#xff0c;支持图片自动压缩&#xff0c;可预览图片 2、合并PDF&#xff0c;支持多个PDF合并成一个PDF 3、PDF转图片&#xff0c;PDF的每页转成一张图片 4、OFD转PDF&#xff0c;OFD办公常用于国内的…

Linux 基金会创建高性能软件基金会 (HPSF)

导读Linux 基金会宣布&#xff0c;他们正在组建高性能软件基金会 (High Performance Software Foundation, HPSF)&#xff0c;以帮助推进高性能计算 (HPC) 核心开源项目的发展&#xff0c;包括 Spack, Kokkos, AMReX, VTK-m, HPCToolkit, E4S, Charliecloud, WarpX&#xff0c;…

【SQL Server2019SSMS】安装 | 卸载手册

目录 &#x1f4cb;前言 ⛳️【SQL Serverssms】安装 1. SQL Server自定义安装 2. SSMS安装 ⛳️【SQL Server】卸载 &#x1f4cb;前言 &#x1f308;个人主页&#xff1a;Sarapines Programmer &#x1f525; 系列专栏&#xff1a;本期文章收录在《宝藏工具使用手册》&am…

vscode 查看某个组件的引用和依赖关系

Dependency Cruiser Extension插件 安装vscode插件Dependency Cruiser Extension 安装完成后&#xff0c;在任何一个文件处右键&#xff0c;选择view dependencies&#xff0c;即可查看依赖关系。 如&#xff0c;我们查看了AppMain.vue这个文件的引用和被引用文件。如下图&…

MySQL慢查询测试实践

1.开启慢查询的目的 开启慢查询日志&#xff0c;可以让MySQL记录下查询超过指定时间的语句&#xff0c;通过定位分析性能的瓶颈&#xff0c;才能更好的优化数据库系统的性能。 2.设置mysql慢查询 方法一&#xff1a;全局变量设置&#xff08;临时生效&#xff09; 将 slow_q…

关于‘NoneType‘ object has no attribute ‘endswith‘问题

这是个调用文件&#xff0c;相当于一个工具&#xff0c;不能单独使用&#xff0c;所以运行会报这个错误。

12V 全桥驱动芯片GC9008,0.1A 持续驱动输出电流,可替代MX6208

GC9008 是一款 12V 全桥驱动芯片&#xff0c;为 摄像机、消费类产品提供高性价比的方案。能提供 0.1A 的持续输出电流。 可以工作在 4.5~15V 的电源电压上。 GC9008 具有 PW &#xff08; IN1/IN2 &#xff09;输入接口 , 与行业标准器件兼容. GC9008S 是 SOP8 封装&a…

自己动手实现一个深度学习算法——八、深度学习

深度学习是加深了层的深度神经网络。 1.加深网络 1&#xff09;向更深的网络出发 创建一个如下图所示的网络结构的CNN 这个网络的层比之前实现的网络都更深。这里使用的卷积层全都是33 的小型滤波器&#xff0c;特点是随着层的加深&#xff0c;通道数变大&#xff08;卷积…

Centos 如何判断分区是mbr还是gpt格式

1 介绍 MBR 自20世纪80年代初以来的标准分区表格式每个驱动器最多支持四个主分区最多可以划分2TB的磁盘 GPT GPT是MBR分区表格式的后续每个驱动器最多支持128个分区可以将一个磁盘分区到最大到18艾字节 对小于2TB的磁盘使用MBR对大于2TB的磁盘使用GTP 2 查询方式 2.1 fdis…

Windows11安装后跳过联网登录

Windows11安装后跳过联网登录 实验设备&#xff1a; VMware17Pro虚拟机中使用Windows11镜像安装Windows11操作系统&#xff0c;并且在虚拟机中测试跳过联网登录。 步骤 说明&#xff1a;物理卸载网卡&#xff08;在虚拟机上禁用网卡&#xff09;没用 思路&#xff1a; sh…

鸿蒙应用开发-初见:ArkTS

作者&#xff1a;HarderCoder ArkTS ArkTS围绕应用开发在 TypeScript &#xff08;简称TS&#xff09;生态基础上做了进一步扩展&#xff0c;继承了TS的所有特性&#xff0c;是TS的超集 ArkTS在TS的基础上扩展了struct和很多的装饰器以达到描述UI和状态管理的目的 基本语法 …

【云备份】配置加载文件模块

文章目录 配置信息设计配置文件加载cloud.conf配置文件单例模式的使用ReadConfigFile —— 读取配置文件GetInstance —— 创建对象其他函数的实现 具体实现cloud.confconfig.hpp 配置信息设计 使用文件配置加载一些程序运行的关键信息 可以让程序的运行更加灵活 配置信息&am…

kafka集群环境部署

文章目录 1 Kafka集群2 搭建两台服务器2.1 zookeeper部署2.2 启动1号机器的broker2.3 启动2号机器的broker2.4 查看kafka集群2.5 测试集群 1 Kafka集群 2 搭建两台服务器 2.1 zookeeper部署 zookeeper先只部署一台&#xff0c;在1号机器&#xff08;192.168.11.59&#xff09;…

浅谈智能照明控制系统在建筑电气工程中的应用

贾丽丽 安科瑞电气股份有限公司 上海嘉定 201801 摘要&#xff1a;建筑电气工程是项目工程中的重要组成部分&#xff0c;其对技术、电气设备及系统的要求较高。在信息化技术不断深入推广的新时期&#xff0c;建筑电气工程中的照明系统获得新的发展契机&#xff0c;为了满足现…