【教程】C++语言基础学习笔记(七)——Array数组

文首标志
写在前面:
如果文章对你有帮助,记得点赞关注加收藏一波,利于以后需要的时候复习,多谢支持!


【C++语言基础学习】系列文章

第一章 《项目与程序结构》
第二章 《数据类型》
第三章 《运算符》
第四章 《流程控制》
第五章 《Vector向量》
第六章 《String字符串》
第七章 《Array数组》
第八章 《函数》
第九章 《指针》
第十章 《结构体》


文章目录

  • 【C++语言基础学习】系列文章
  • 一、一维数组
    • (一)一维数组定义方式
    • (二)一维数组数组名
    • (三)冒泡排序算法
  • 二、二维数组
    • (一)二维数组定义方式
    • (二)二维数组数组名


C++支持数组数据结构,其可以储存一个固定大小的相同类型元素的顺序集合。数组被用来储存一系列数据,但它往往被认为是一系列相同类型的变量。
数组的声明并不是声明一个个单独的变量,比如number0number1、……、number99等,而是声明一个数组变量,比如numbers,然后使用numbers[0]numbers[1]、……、numbers[99]等来代表一个个单独的变量。数组中的特定元素可以通过索引访问。
所有的数组都是由连续的内存位置组成。最低的地址对应第一个元素,最好的地址对应最后一个元素。

一、一维数组

(一)一维数组定义方式

在C++中要声明一个数组,一般有三种方式。

数据类型 数组名[ 数组长度 ];// 第一种定义方式
数据类型 数组名[ 数组长度 ] = {1,2, ... };// 第二种定义方式
数据类型 数组名[] = {1,2, ... };// 第三种定义方式

以下是简单的示例。

// 第一种
int arr1[3];
arr1[0] = 10;
arr1[1] = 12;
arr1[2] = 17;
// 第二种
int arr2[3] = { 10,12,17 };
// 第三种
int arr3[] = { 10,12,17 };

第一种方式定义了一个数组arr1具有三个元素,然后逐一赋值。值得注意的是数组元素下标的引用是从0开始的。
第二种方式定义数组arr2也具有三个元素,但此方式将三个元素的值直接通过{}分别赋予。而当给元素赋值不完全时(如四个元素赋三个值),按顺序剩下的没有赋值的元素初始化值默认为0,即没有赋值完的元素用0填充。
第三种方式定义的数组arr3不需要定义数组长度,直接初始化各个元素的具体值即可。但也需要注意的是不能不初始化任何元素的值,会导致编译器检测不出这个数组的长度,以至于报错。

(二)一维数组数组名

一维数组的数组名是指数组在内存中存储的起始地址。在C语言中,声明一个一维数组时,可以将一个标识符用作数组名。例如,如果声明一个名为arr的一维整型数组,那么arr就是该数组的数组名。
总结来说,一维数组名称的用途有两个。

  1. 可以统计整个数组在内存中的长度
  2. 可以获取数组在内存中的首地址

统计占用内存的长度也是使用sizeof()来查看。

int arr[3] = { 1,3,5 };
cout << "整个数组占用内存空间为:" << sizeof(arr) << endl;
cout << "每个元素占用内存空间为:" << sizeof(arr[0]) << endl;
cout << "数组中的元素个数为:" << sizeof(arr) / sizeof(arr[0]) << endl;

返回结果如下。

整个数组占用内存空间为:12
每个元素占用内存空间为:4
数组中的元素个数为:3

而获取数组首地址直接输出数组即可。

int arr[3] = { 1,3,5 };
cout << "数组首地址(十六进制)为:" << arr << endl;// 十六进制
cout << "数组首地址(十进制)为:" << (int)arr << endl;// 十进制
cout << "数组中第一个元素地址为:" << &arr[0] << endl;

返回结果如下。

数组首地址(十六进制)为:00000018F958FB28
数组首地址(十进制)为:-111609048
数组中第一个元素地址为:00000018F958FB28

承接上一个示例,如果希望得到十六进制的首地址返回结果,直接输出数组即可;而如果希望得到十进制结果,则需要将数组转换为整型;若希望得知数组内某个元素的首地址,则需要使用取值运算符&来输出。
值得注意的是数组名是常量,不可以进行赋值操作。

(三)冒泡排序算法

冒泡排序是一种简单的排序算法,它通过依次比较相邻的元素并交换它们的位置来将一个数组按照升序或降序排列。冒泡排序的基本思想是,每一轮扫描将相邻的两个元素比较并交换位置,使得最大(或最小)的元素像气泡一样逐渐浮到数组的末尾。
简单来讲就是对数组内的元素实现了从小到大(从大到小)顺序的排列。由于结构简单,使得冒泡排序成为最常用的排序算法。
其规则如下。

  1. 从第一个元素开始,依次比较相邻的两个元素。
  2. 如果前一个元素大于(或小于)后一个元素,则交换它们的位置。
  3. 继续向后比较并交换,直到最后一个元素,这样一轮比较下来,最大(或最小)的元素就会被交换到最后。
  4. 重复执行步骤 1~3,每一轮比较都会确定一个最大(或最小)的元素的位置。
  5. 当没有发生元素交换时,排序结束。

下面是利用冒泡排序算法实现升序序列的示例。

int arr[9] = { 4,2,8,0,5,7,1,3,9 };
cout << "排序前:" << endl;
for (int i = 0; i < 9; i++)
{cout << arr[i] << " ";
}
cout << endl;

首先,定义一个乱序的数组,用循环遍历输出一下此时数组内的排序。
返回结果如下。

排序前:
4 2 8 0 5 7 1 3 9

此时回想冒泡排序算法的原理,可以得知对9个数的排列,从需要比较的第一个数字到最后一个数字其实只有8轮(第8个数字和第9个数字比较即为最后一轮),所以排序总轮数=元素个数-1;而观察可以得知,每轮对比次数=元素个数-排序轮数-1,以此规律设计冒泡排序算法。
全部代码如下。

#include "test.h"
#include <iostream>using namespace std;void test::Test()
{int arr[9] = { 4,2,8,0,5,7,1,3,9 };cout << "排序前:" << endl;for (int i = 0; i < 9; i++){cout << arr[i] << " ";}cout << endl;// 冒泡排序// 总共排序轮数=元素个数-1for (int i = 0; i < 9 - 1; i++){// 内层循环对比=每轮对比次数=元素个数-排序轮数-1for (int j = 0; j < 9 - i - 1; j++){// 如果第一个数字比第二个数字大,则交换两个数字if (arr[j] > arr[j + 1]){// 创建临时变量承载第一个位置上较大的数字int temp = arr[j];// 令第二个位置上较小的数字转移到第一个位置上arr[j] = arr[j + 1];// 令第二个位置取回原本第一个位置上那个较大的数字arr[j + 1] = temp;}}}cout << "排序后:" << endl;for (int i = 0; i < 9; i++){cout << arr[i] << " ";}cout << endl;
}

返回结果如下。

排序前:
4 2 8 0 5 7 1 3 9
排序后:
0 1 2 3 4 5 7 8 9

二、二维数组

C++支持多维数组。在 C++语言中,可以使用多维数组来存储具有多个维度的元素集合。多维数组实际上是数组的数组,每个维度都可以有自己的大小。多维数组声明的一般形式如下。

type name[size1][size2]...[sizeN];

这里主要以二维数组作为示例进行介绍。

(一)二维数组定义方式

在C++中要声明一个二维数组,一般有四种方式。

数据类型 数组名[ 行数 ][ 列数 ];// 第一种定义方式
数据类型 数组名[ 行数 ][ 列数 ] = { { 数据1,数据2 },{ 数据3,数据4 } };// 第二种定义方式
数据类型 数组名[ 行数 ][ 列数 ] = { 数据1,数据2,数据3,数据4 };// 第三种定义方式
数据类型 数组名[][ 列数 ] = { 数据1,数据2,数据3,数据4 };// 第四种定义方式

对于第一种定义方式,test.cpp示例代码如下。

#include "test.h"
#include <iostream>using namespace std;void test::Test()
{// 第一种定义方式int arr1[2][3];arr1[0][0] = 1;arr1[0][1] = 2;arr1[0][2] = 3;arr1[1][0] = 4;arr1[1][1] = 5;arr1[1][2] = 6;// 外层循环打印行数,内层循环打印列数for (int i = 0; i < 2; i++){for (int j = 0; j < 3; j++){cout << arr1[i][j] << " ";}cout << endl;}
}

按第一种方式,定义一个2行3列的arr1二维数组,并逐个赋值,结果可以用for循环来遍历数组内容。返回结果如下。

1 2 3
4 5 6

对于第二、三、四种定义方法,承接上一个示例,test.cpp代码如下。

// 第二种定义方式
int arr2[2][3] =
{{ 1,2,3 },{ 4,5,6 }
};
// 第三种定义方式
int arr3[2][3] = { 1,2,3,4,5,6 };
// 第四种定义方式
int arr4[][3] = { 1,2,3,4,5,6 };

对于第二种定义方式,行和列的元素赋值明显,通常是最常用也是可读性最强的一种定义方式;而第三种则是在定义了行数和列数后,编译器仍能正确分类每个元素的行数和列数,从而达到预期赋值效果;第四种的原理同第三种定义方式,面对一串元素,在只有两个维度的条件下,即便仅定义了列数,编译器也能从总元素数中得出行数,从而分配赋值。需要注意的是,虽然在定义中可以省略行数,但列数却不可以省略。
代码返回结果和上一个示例相同,故不再展示。

(二)二维数组数组名

与一维数组同理,二维数组数组名也可以查看占用内存空间大小和首地址。

int arr[2][3] =
{{ 1,2,3 },{ 4,5,6 }
};
cout << "二维数组占用内存空间为:" << sizeof(arr) << endl;
cout << "二维数组第一行占用内存空间为:" << sizeof(arr[0]) << endl;
cout << "二维数组第一个元素占用内存空间为:" << sizeof(arr[0][0]) << endl;
cout << "二维数组中的行数为:" << sizeof(arr) / sizeof(arr[0]) << endl;
cout << "二维数组中的列数为:" << sizeof(arr[0]) / sizeof(arr[0][0]) << endl;
cout << "二维数组首地址(十进制)为:" << (int)arr << endl;
cout << "二维数组第一行首地址为:" << (int)arr[0] << endl;
cout << "二维数组第二行首地址为:" << (int)arr[1] << endl;
cout << "二维数组第一个元素首地址为:" << (int)&arr[0][0] << endl;
cout << "二维数组第五个元素首地址为:" << (int)&arr[1][2] << endl;

返回结果如下。

二维数组占用内存空间为:24
二维数组第一行占用内存空间为:12
二维数组第一个元素占用内存空间为:4
二维数组中的行数为:2
二维数组中的列数为:3
二维数组首地址(十进制)为:1781529192
二维数组第一行首地址为:1781529192
二维数组第二行首地址为:1781529204
二维数组第一个元素首地址为:1781529192
二维数组第五个元素首地址为:1781529212

从返回结果来看,二维数组本身、其某一行和某个具体元素之间占用的空间都是成比例的,也就是说每个元素的占用组成了二维数组行列的占用和二维数组本身的占用。对于首地址,值得注意的是二维数组本身的首地址、第一行的首地址、第一个元素的首地址是相同的;而对于第一行和第二行的首地址相差正好是第一行的占用数。


我是EC,一个永远在学习中的探索者,关注我,让我们一起进步!

文末标志

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

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

相关文章

Linux_进程概念

硬件系统 软件系统 进程概念 进程状态 孤儿进程 进程优先级 一.硬件系统 1.1 冯诺依曼体系结构 数学家冯诺依曼提出了计算机制造的三个基本原则&#xff0c;即采用二进制逻辑、程序存储执行以及计算机由五个部分组成&#xff08;运算器、控制器、存储器、输入设备、输出设备&a…

Python学习之路-爬虫提高:scrapy基础

Python学习之路-爬虫提高:scrapy基础 为什么要学习scrapy 通过前面的学习&#xff0c;我们已经能够解决90%的爬虫问题了&#xff0c;那么scrapy是为了解决剩下的10%的问题么&#xff0c;不是&#xff0c;scrapy框架能够让我们的爬虫效率更高 什么是scrapy Scrapy是一个为了…

tee漏洞学习-翻译-3:TrustZone exploit for MSM8974

原文&#xff1a;http://bits-please.blogspot.com/2015/08/full-trustzone-exploit-for-msm8974.html 在这篇博文中&#xff0c;我们将介绍利用上一篇文章中描述的 TrustZone 漏洞的完整过程。 在开发此漏洞时&#xff0c;我只使用了我值得信赖的&#xff08;个人&#xff0…

120.乐理基础-五线谱-五线谱的多声部与指法问题

内容参考于&#xff1a;三分钟音乐社 上一个内容&#xff1a;119.乐理基础-五线谱-五线谱的标记-CSDN博客 五线谱多声部与简谱的多声部一样&#xff1a;简谱的多声部 五线谱多声部例子&#xff1a;钢琴谱 另一个例子&#xff1a;在纵向上有多个音符 然后放大之后&#xff0c…

【51单片机】利用【时间延迟】的原理规避【按键抖动问题】

前言 大家好吖&#xff0c;欢迎来到 YY 滴单片机系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过单片机的老铁 本章是51LCD单片机设计的一个环节&#xff0c;完整可前往相应博客查看完整传送门 欢迎订阅 YY滴C专栏&#xff01;更多干货持续更新&#xff01;以下…

详解CC++内存管理(new和delete)

文章目录 写在前面1. C&C内存分布2. C语言中动态内存管理方式&#xff1a;malloc/calloc/realloc/free3. C内存管理方式&#xff08;语法&#xff09;3.1 new/delete操作内置类型3.2 new和delete操作自定义类型 4. new和delete的实现原理4.1 operator new与operator delete…

数据结构——6.2 图的存储与基本操作

6.2 图的存储与基本操作 概念 图的存储 邻接矩阵存有向图和无向图 根据邻接矩阵求度&#xff1a; 无向图&#xff1a;第i个结点的度 第i行 (或第列) 的非零元素个数 有向图&#xff1a; 第i个结点的出度 第i行的非零元素个数 第i个结点的入度 第i列的非零元素个数 第i个结…

Stable Diffusion教程——stable diffusion基础原理详解与安装秋叶整合包进行出图测试

前言 在2022年&#xff0c;人工智能创作内容&#xff08;AIGC&#xff09;成为了AI领域的热门话题之一。在ChatGPT问世之前&#xff0c;AI绘画以其独特的创意和便捷的创作工具迅速走红&#xff0c;引起了广泛关注。随着一系列以Stable Diffusion、Midjourney、NovelAI等为代表…

linux信号机制[一]

目录 信号量 时序问题 原子性 什么是信号 信号如何产生 引入 信号的处理方法 常见信号 如何理解组合键变成信号呢&#xff1f; 如何理解信号被进程保存以及信号发送的本质&#xff1f; 为什么要有信号 信号怎么用&#xff1f; 样例代码 core文件有什么用呢&#…

Docker基础与持续集成

docker 基础知识&#xff1a; docker与虚拟机 !左边为虚拟机&#xff0c;右边为docker环境 – Server :物理机服务器Host OS &#xff1a;构建的操作系统Hypervisor &#xff1a;一种虚拟机软件&#xff0c;装了之后才能虚拟化操作系统Guest OS &#xff1a;虚拟化的操作系统…

自动驾驶轨迹规划之kinodynamic planning

欢迎大家关注我的B站&#xff1a; 偷吃薯片的Zheng同学的个人空间-偷吃薯片的Zheng同学个人主页-哔哩哔哩视频 (bilibili.com) 本文PPT来自深蓝学院《移动机器人的运动规划》 目录 1.kinodynamic的背景 2. old-school pipline 3.example 1.kinodynamic的背景 kinodynami…

java之jvm详解

JVM内存结构 程序计数器 Program Counter Register程序计数器(寄存器) 程序计数器在物理层上是通过寄存器实现的 作用&#xff1a;记住下一条jvm指令的执行地址特点 是线程私有的(每个线程都有属于自己的程序计数器)不会存在内存溢出 虚拟机栈(默认大小为1024kb) 每个线…

LeetCode、739. 每日温度【中等,单调栈】

文章目录 前言LeetCode、739. 每日温度【中等&#xff0c;单调栈】题目链接及分类思路单调栈 资料获取 前言 博主介绍&#xff1a;✌目前全网粉丝2W&#xff0c;csdn博客专家、Java领域优质创作者&#xff0c;博客之星、阿里云平台优质作者、专注于Java后端技术领域。 涵盖技…

二次元自适应动态引导页

源码介绍 二次元自适应动态引导页&#xff0c;HTMLJSCSS&#xff0c;记事本修改&#xff0c;上传到服务器即可&#xff0c;也可以本地双击index.html查看效果 下载地址 https://wfr.lanzout.com/isRem1o7bfcb

MockServer 服务框架设计

大部分现有的 mock 工具只能满足 HTTP 协议下简单业务场景的使用。但是面对一些复杂的业务场景就显得捉襟见肘&#xff0c;比如对 socket 协议的应用进行 mock&#xff0c;或者对于支付接口的失败重试的定制化 mock 场景。 为解决上述问题&#xff0c;霍格沃兹测试学院设计并研…

零基础学编程怎么入手,中文编程工具构件箱之多页面板构件用法教程,系统化的编程视频教程上线

零基础学编程怎么入手&#xff0c;中文编程工具构件箱之多页面板构件用法教程&#xff0c;系统化的编程视频教程上线 一、前言 今天给大家分享的中文编程开发语言工具资料如下&#xff1a; 编程入门视频教程链接 http://​ https://edu.csdn.net/course/detail/39036 ​ …

下一代块存储重新定义任务关键型存储架构

HPE 宣布全面推出基于 HPE Alletra Storage MP 构建的 HPE GreenLake for Block Storage 第 3 版&#xff0c;提供业界首款分解式横向扩展块存储&#xff0c;并提供 100% 数据可用性保证。这种独特的块存储产品由共享一切存储架构提供支持&#xff0c;并通过 HPE GreenLake 云平…

(算法3)二分查找

朴素二分查找 最直接的二分查找&#xff0c;有序&#xff0c;查找数组中的某个元素 这种方法是有局限性的&#xff1a;只可以查找升序的数组&#xff0c;且要查找的元素是一个 注意&#xff1a;mid(中点&#xff09;的计算应该是&#xff1a;left(right-left)/2 (个数是偶数时…

接口测试06 -- pytest接口自动化封装Loggin实战

1. 接口关键字封装 1.1 基本概念 接口关键字封装是指:将接口测试过程中常用的操作、验证封装成可复用的关键字(或称为函数、方法),以提高测试代码的可维护性和可复用性。 1.2 常见的接口关键字封装方式 1. 发送请求:封装一个函数,接受参数如请求方法、URL、请求头、请求…

基于Spring Boot的美容院管理系统设计与实现,计算机毕业设计(带源码+论文)

源码获取地址&#xff1a; 码呢-一个专注于技术分享的博客平台一个专注于技术分享的博客平台,大家以共同学习,乐于分享,拥抱开源的价值观进行学习交流http://www.xmbiao.cn/resource-details/1757434902285987841