C++ 数组详解

2023-11-01

  • C++ 支持数组数据结构,它可以存储一个固定大小的相同类型元素的顺序集合。数组是用来存储一系列数据,但它往往被认为是一系列相同类型的变量。


1. 数组初始化

  在 C++ 中要声明一个数组,需要指定元素的类型和元素的数量,如下所示:
  通用格式:typeName arrayName[ arraySize ];

// 如: age 是一个数组,可容纳10个类型为int 元素。
int age[10];

  • I. 只有在定义数组时才可以使用初始化。
  • II. 不能将一个数组赋值给另一个数组。
int cards[4] = {1,2,3,4};	// 正确初始化 1
int age[4];					// 正确初始化 2

age[4] = {1,2,3,4}			// 错误1
age = cards;				// 错误2
  • 此外还可以这样初始化:
int cards[100] = {1};				// 正确初始化 3: 第一个元素为1,后续99个元素为int默认类型0
short age[] = {1,2,3,4,5};			// 正确初始化 4: 需要编译器来计算元素个数
double score[3]{1.0, 2.0, 90.0};	// 正确初始化 5: c++11新增

double score[3] = {};				// 所有元素初始化为0
double score[3]{}// 所有元素初始化为0
  • 重点: 这里说一下数组初始化默认值
  • I. 做全局变量时,不使用花括号{}时,元素全部初始化为类型默认值,如 int-0
  • II. 做局部变量时,不使用花括号{}时,元素为类型随机值。
  • III. 使用花括号{}时,中数据按顺序初始化至数组内,剩余元素全部初始化为类型默认值,如 int-0
int num[5];                     // 1. 全局变量,默认int-0

int main() {

    cout << "array num  :"; 
    for (auto& i:num)
        cout << i << ", ";

    int score[5];               // 2. 局部变量,默认类型随机值
    cout << "\narray score:"; 
    for (auto& i:score)
        cout << i << ", ";

    int age[5] = {1,2};
    cout << "\narray age  :";   // 3. 使用花括号‘{}’时
    for (auto& i:age)
        cout << i << ", ";

    cout << endl;
    return 0;
}

array num :0, 0, 0, 0, 0,
array score:2, 0, 4197709, 0, 0,
array age :1, 2, 0, 0, 0,


2. char 数组

  • C-风格的字符串将字符存储与数组中,其性质如下:
  • I. 以空字符null-char为结尾,空字符写作\0,其ASCII码值为0,用来标记字符串的结尾。 如:
char name[4] = {'y','u','a','n'};		// 字符数组,这不是字符串
char name[5] = {'y','u','a','n','\0'};	// 字符串
  • C++中 使用std::cout<< name; 进行打印,他们会逐个处理字符,直至出现空字符\0为止。
  • 打印上述中第一个name, 打印完数组中元素后,将打印数组后的内存,直至打印到空字符\0为止。
  • 打印第二个name,将不会出现上述情况。

  • II. 用引号将字符串括起来,这种字符串被称为字符串常量:
int main() {

    char name[10] = "yuan.";
    cout << name << endl;		// 打印: yuan.

    cout << endl;
    return 0;
}
  • 这种形式的将字符串读取到char数组中时,将自动加上空字符\0。剩余元素设置为char-\0
  • 上述name包含10个字符:{'y', 'u', 'a', 'n', '.', '\0', '\0', '\0', '\0', '\0'};

  • III. 双引号: 字符串常量(双引号)不能与字符常量(单引号)互换。
char temp = 's';			// 这样可以
char temp = "s";			// 这样不行,"s" 表示是两个字符:'s' 和 '\0'组成的字符串
  • 更糟糕的是,"s"实际上表示的是字符串所在的内存地址,上述语句将内存地址赋值给char类型,编译器不容许这种不合理的操作。

  • IV. 拼接字符串常量:
  • C++允许拼接字符串字面值,任何由空白、空格、制表符、换行符分隔的字符串都会自动进行拼接成一个。
int main() {

    cout << "name:" "yuan-fufu." << endl;   // 空格
    cout << "age:"  "18." << endl;          // 制表符
    cout << "sex:"
            "boy." << endl;                 // 换行

    cout << endl;
    return 0;
}

name:yuan-fufu.
age:18.
sex:boy.


3. 指针、动态数组


  [1]. 这里讲一下指针:

  • I. 指针名表示的是地址
  • II. *运算符称为 解引用运算符,将其用到指针,可以得到该地址处的值。
  • III. 对变量应用地址运算符&,就可以得到其地址,
  • IV. 对于每一个指针变量的初始化,都需要使用一个*
int num = 10;
int* int_ptr = &num;	// 将int_ptr 的值设置为 num的地址

int* p1,p2; 			// 创建一个指针p1,以及一个int变量p2.

   使用new分配内存:

int* ptr = new int;		// new找到一块能存储int类型的地址,将地址返回,ptr的值 设置为该地址
delete ptr;				// 释放ptr 指向的地址内存, 不会删除ptr 本身
delete ptr;				// 重复释放,对空指针使用delete是安全的

int age = 10;
prt = &age;				// ptr还可以用

  例子代码:

int main() {
    int* p = new int;
    *p = 10;
    cout << *p << endl;		// 打印 10
    delete p;

    int a = 200;
    p = &a;
    cout << a << endl;		// 打印 200

    cout << endl;
    return 0;
}
  • 不使用delete并将p指向其他变量,将会发生内存泄露,newdelete匹配使用。

  一般来说,在64位系统下,指针长度为8个字节,32位系统下,指针长度为4个字节;
  
   以下为解释:
   首先,指针变量存储的是地址,而地址是内存单元的编号。所以,一个指针占几个字节,等于是一个地址的内存单元编号有多长。
   在计算机中,CPU不能直接与硬盘进行数据交换,CPU只能直接跟内存进行数据交换。而CPU是通过数据总线、地址总线、控制总线三条线与内存进行数据传输与操作。其中
     1. 地址总线的宽度决定了CPU的寻址能力;
     2. 控制总线决定了CPU对其他控件的控制能力以及控制方式。
     3. 数据总线的宽度决定了CPU单次数据传输的传送量,也就是数据传输速度;
  
   我们平时所说的计算机是64位、32位、16位,指的是计算机CPU中通用寄存器一次性处理、传输、暂时存储的信息的最大长度。即CPU在单位时间内(同一时间)能一次处理的二进制数的位数。
   假如,某计算机的地址总线是32位,那么每次寻址的空间为0x0000 0000 0000 0000 ~ 2^32-1,那么CPU的最大内存为2^32Byte = 4294967296 Byte = 4GB。也就是说32位地址线的寻址空间(电脑内存)封顶即为4GB。
   所以32位操作系统中, sizeof(double *)==sizeof(int *)==sizeof(char *)==32/8 == 4 Byte

   32位中: 1位=1bit=1比特,表示一个二进制0或1。
   1字节(Byte) = 8比特(bit)。


  [2]. 动态数组:

  • 通用格式:type_name* ptr_name = new type_name[element_size];
  • 创建包含10个int元素的数组:
int* ptr = new int[10];		// new 分配内存
delete [] ptr;				// delete [] 释放整个数组,而不是仅指针指向的元素 
  • ptr指向数组第一个元素,因此把指针当做数组名用就可以。
  • 多数情况下,C++把数组名解释为数组第一个元素的地址。

   测试代码:

int main() {

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

    cout << ptr << endl;
    cout << arr << endl;
    cout << &arr[0] << endl;
    

    cout << *(ptr+1) << endl;
    cout << ptr[1] << endl;
    
    cout << arr[1]   << endl;
    cout << *(arr+1) << endl;

    cout << endl;
    return 0;
}

0x7ffe779a3890
0x7ffe779a3890
0x7ffe779a3890
2
2
2
2

  • 总结:
  • <1>. 数组名指针数组第一个元素 的打印相同, 均表示数组第一个元素的地址。
  • <2>. C++编译器会将arr[1]看作*(arr+1),因此*(arr+1)arr[1]等价:

arr_name[i]*(arr_name+i) 可相互转换。

  • <3>. ptr存储数组第一个元素的地址,为int类型指针,因此ptr+1表示arr[1]的地址,同上,*(ptr+1)也可用prt[1]表示:

ptr_name[i]*(ptr_name+i) 可相互转换

  • 多数情况下,可以使用相同的方式使用 数组名指针名,二者区别在于:
  • <1>. 可以修改指针指向的地址,数组名是常量
  • <2>. sizeof(指针名)为指针长度,sizeof(数组名)为数组长度。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++ 数组详解 的相关文章

  • 更新面板工作速度非常慢

    我正在编写一个用户可以注册的应用程序 注册时 可以选择多个选项 并根据这些注册字段可见或不可见以及是否必需 我想出了一个想法 所有字段都将位于 updatePanel 中 当用户更改注册选项时 我将在服务器端设置这些字段的可见性 它可以工作
  • 在 HKCR 中创建新密钥有效,但不起作用

    我有以下代码 它返回 成功 但使用两种不同的工具使用搜索字符串 3BDAAC43 E734 11D5 93AF 00105A990292 搜索注册表不会产生任何结果 RegistryKey RK Registry ClassesRoot C
  • C# 方法重载决策不选择具体的泛型覆盖

    这个完整的 C 程序说明了这个问题 public abstract class Executor
  • 将类对象放置在向量中?

    我注意到我可以将一个类放置在一个向量中 这是我的程序 我收到以下错误 out blackjack exe blackjack obj blackjack obj error LNK2019 unresolved external symbo
  • 按扩展名过滤搜索文件返回太多结果

    我正在开发一个 C 控制台应用程序 它必须管理 Windows 操作系统上的文件 我需要获取具有特定扩展名的文件名 列表 我找到了很多解决方案 最建议的是以下一种 HANDLE hFind WIN32 FIND DATA data hFin
  • 有些有助于理解“产量”

    在我不断追求少吸的过程中 我试图理解 产量 的说法 但我不断遇到同样的错误 someMethod 的主体不能是迭代器块 因为 System Collections Generic List 不是迭代器接口类型 这是我被卡住的代码 forea
  • extern 声明和函数定义都在同一文件中

    我只是浏览了一下gcc源文件 在gcc c 我发现了类似的东西 extern int main int char int main int argc char argv 现在我的疑问是extern是告诉编译器特定的函数不在这个文件中 但可以
  • 如何将 .txt 文件中的数据转换为 xml? C#

    我在一个文本文件中有数千行数据 我想通过将其转换为更容易搜索的内容来轻松搜索 我希望 XML 或其他类型的大型数据结构 尽管我不确定它是否是最好的对于我的想法 每行的数据如下所示 第 31 册 托马斯 乔治 32 34 154 每本书都不是
  • 是否使用 C# 数据集? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我对 C 中的数据集概念有点困惑 编码 ASP NET 站点 但这并不重要 在我的阅读中 我了解到它们 本质上 用作我的应用程序和我的
  • 从网页运行 ClickOnce 应用程序,无需用户操作

    我们有一个基于 Java 的 Web 应用程序以及用 C 编写的相同应用程序 如果 java 检查器发现客户端计算机上没有安装 Java 则应该运行该应用程序 这个想法是运行 C 单击一次 http en wikipedia org wik
  • 如何递归取消引用指针(C++03)?

    我正在尝试在 C 中递归地取消引用指针 如果传递一个对象 那就是not一个指针 这包括智能指针 我只想返回对象本身 如果可能的话通过引用返回 我有这个代码 template
  • 如果输入被重定向则执行操作

    我想知道如果我的输入被重定向 我应该如何在 C 程序中执行操作 例如 假设我有已编译的程序 prog 并且我将输入 input txt 重定向到它 我这样做 prog lt input txt 我如何在代码中检测到这一点 一般来说 您无法判
  • 在 C# 中为父窗体中的子窗体控件添加事件处理程序

    我有两种形式 一种是带有按钮和文本框的父表单 单击该按钮时 将打开一个对话框 该子窗体又包含一个文本框和一个按钮 现在我想要的是 每当子表单文本框中的文本更改时 父表单文本框中的文本会自动更改 为了获得这个 我所做的是 Form3 f3 n
  • 在 C 中使用枚举而不是 #defines 作为编译时常量是否合理?

    在 C 工作了一段时间后 我将回到 C 开发领域 我已经意识到 在不必要的时候应该避免使用宏 以便让编译器在编译时为您做更多的工作 因此 对于常量值 在 C 中我将使用静态 const 变量或 C 11 枚举类来实现良好的作用域 在 C 中
  • Visual Studio 2015:v120 与 v140?

    仅供参考 Win10 x64 我今天开始尝试 Visual Studio 2015 在弄清楚如何运行 C C 部分后 我尝试加载一个大型个人项目 该项目使用非官方的glsdk http glsdk sourceforge net docs
  • 将 Lambda 表达式树与 IEnumerable 结合使用

    我一直在尝试了解有关使用 Lamba 表达式树的更多信息 因此我创建了一个简单的示例 这是代码 如果作为 C 程序粘贴到 LINQPad 中 它可以工作 void Main IEnumerable
  • WPF DataGrid / ListView 绑定到数组 mvvm

    我们假设你有 N 个整数的数组 表示行数的整数值 在模型中 该整数绑定到视图中的 ComboBox Q1 如何将数组 或数组的各个项目 绑定到 DataGrid 或 ListView 控件 以便 当您更改 ComboBox 值时 只有那么多
  • 没有“对 *this”功能的右值引用的解决方法

    我有一个围绕可移动对象的代理容器类 并希望代理能够隐式生成对底层对象的右值引用 但仅当代理本身被移动时 我相信我将能够按照提案 n2439 实施此行为 将移动语义扩展到 this http www open std org jtc1 sc2
  • 为什么空循环使用如此多的处理器时间?

    如果我的代码中有一个空的 while 循环 例如 while true 它将把处理器的使用率提高到大约 25 但是 如果我执行以下操作 while true Sleep 1 它只会使用大约1 那么这是为什么呢 更新 感谢所有精彩的回复 但我
  • 我可以使用 lambda 函数或 std::function 对象来代替函数指针吗?

    我有一个需要使用的库 它定义了以下内容 typedef void CallbackFunction const int i 并且有一个注册回调的函数 如下所示 void registerCallback CallbackFunction p

随机推荐

  • STM32 的中断解析

    中断定义及其执行过程 中断是指在主程序运行过程中 出现了特定的中断触发条件 中断源 使得CPU暂停当前正在运行的程序 转而去处理中断程序 处理完成后又返回原来被暂停的位置继续运行 STM32微控制器有68个可屏蔽中断通道 包含EXTI TI
  • 如何设置PCB过孔盖油 AD、 Protel 99 SE、 PADS Layout

    关于 过孔盖油 和 过孔开窗 此点 许多客户下单时经常会问这是什么意思 就此问题点 说明如下 过孔盖油 1 下单上传的是pcb文件 并在下单时勾选过孔盖油 做板工艺就是过孔盖油 2 下单上传的是gerber文件 按gerber文件生产 忽略
  • Code::Blocks +mingw64 编译64位程序配置方法

    一 准备工作 说明 本人新手一个 最近在用code blocks编程 用的C 由于默认编译器是编译32位的 程序占用系统内存最大只能2g 便考虑编译成64位程序来增大可用内存 于是就上网找方法 可惜网上我搜到的方法试了统统不管用 在破罐子破
  • 百度X福州新区 “数字时代 智领未来”智能网联汽车道路测试正式启动

    9月19日 由福州新区管委会指导 福州市电子信息集团与百度承办的福州新区智能网联汽车道路测试启动仪式暨智能汽车产业科创基地揭牌仪式正式启动 标志着福州新区成为全国首批无人化 商业化政策落地的先行区 成为福建省首个规模化智能网联道路建成区和自
  • OpenCV-图像梯度与边缘提取

    文章目录 图像梯度与边缘提取 Sobel和Scharr算子 cv2 Sobel cv2 convertScaleAbs cv2 Scharr 示例 Laplacian算子 cv2 Laplacian 示例 canny边缘提取 cv2 can
  • “互联网从此没有 BAT”

    燃财经 ID rancaijing 原创 作者 黎明 编辑 魏佳 长期被唱衰的百度 终于到了正式告别BAT的关键时刻 过去30天 受业绩下滑和高管离职等因素影响 百度的股价跌去30 市值蒸发200亿美金 美团趁势赶上 市值一举超越百度 正式
  • 华为OD机试 - 报文回路(Java & JS & Python)

    题目描述IGMP 协议中响应报文和查询报文 是维系组播通路的两个重要报文 在一条已经建立的组播通路中两个相邻的 HOST 和 ROUTER ROUTER 会给 HOST 发送查询报文 HOST 收到查询报文后给 ROUTER 回复一个响应报
  • Incorrect string value: ‘\xE7\x94\x9F\xE4\xBA\xA7...‘ for column ‘ylname‘ at row 1

    1 修改数据库字符集 alter database db new 数据库名 charset utf8mb4 2 修改表字符集 alter table tb 表名 charset utf8mb4 3 修改表字符集和校验规则 alter tab
  • 【第四章:OpenCv阈值分割/二值化(单通道、多通道图片)总结】

    第四章 OpenCv阈值分割 二值化 单通道 多通道图片 总结 0 前言 1 基础知识 1 1 什么是算子 1 2 图像处理中的图像分割技术 1 3 单通道图片的阈值分割 1 4 推荐文章链接 2 灰度图分割 2 1 灰度直方图 2 2 简
  • 在Linux中利用Service命令添加系统服务及开机自启动

    近期由于做嵌入式项目需要 要求将编写的程序在板载系统开机时自启动 这里做个笔记 备忘 1 概念 通过查资料发现linux启动服务是用SERVICE COMMAND 这里的command命令本身也是一个脚本 比如说 service netwo
  • arduino控制RFID门禁卡

    一 实物连接 二 代码实现 include rfid h include
  • NOIp2003 传染病控制

    题目描述 给出一棵树 其中1为根 1号有病 每天向下传染一代 每天可以断一条边 求最小传染数 代码 include
  • IDEA2020.1启动SpringBoot项目出现java程序包:xxx不存在

    Error 3 38 java 程序包org springframework stereotype不存在 Error 4 47 java 程序包org springframework web bind annotation不存在 Error
  • 如何更新anaconda中的所有库(包含自定义环境更新)

    更新base环境下的所有库直接按照以下代码 以管理员身份启动 Anaconda Prompt 升级conda 升级Anaconda前需要先升级conda conda update conda 升级anaconda conda update
  • GBDT模型原理及Python案例分析

    GBDT模型原理及Python案例分析 Gradient Boosting Decision Trees GBDT 是一种常用的机器学习方法 它可以应用于回归和分类问题 相比于其他机器学习模型 GBDT模型具有更高的精确度和更好的泛化能力
  • STM32 进阶教程 12 - M4的硬件乘法器使用

    前言 Cortex M4支持硬件浮点运算单元 有些厂商直接说成DSP模块 本节将给大家介绍STM32F407芯片中硬件浮点运算单元中的使用及带来的性能对比 示例详解 基于硬件平台 正点源子的stm32f4 探索者开发板 MCU 的型号是 S
  • 华为OD机试真题-挑选字符串【2023.Q1】

    题目描述 给定a z 26个英文字母小写字符串组成的字符串A和B 其中A可能存在重复字母 B不会存在重复字母 现从字符串A中按规则挑选一些字母可以组成字符串B挑选规则如下 1 同一个位置的字母只能挑选一次 2 被挑选字母的相对先后顺序不能被
  • Unity中两种播放器

    一 Animator动画播放器 1 简单搭建UI 通过Slider来控制Cube当前状态动画的播放 2 给Cube加上Animator组件 做两个简单的动画 随便做个来回移动的动画就行 注意要关闭动画的循环播放 3 给摄像机挂在脚本 并拖拽
  • sql注入漏洞测试2(初级篇)--为了女神小芳^o^

    今天的的靶场是来自封神台的一个sql注入靶场 图片如下 点击进入传送门 结果如下图所示 先观察网站的url 查看是否有sql注入特征的信息 结果发现没有什么有用信息 但是图片下面有一个超链接 点进去看看 进去之后看到了网站的url有我们想要
  • C++ 数组详解

    C 支持数组数据结构 它可以存储一个固定大小的相同类型元素的顺序集合 数组是用来存储一系列数据 但它往往被认为是一系列相同类型的变量 1 数组初始化 2 char 数组 3 指针 动态数组 1 数组初始化 在 C 中要声明一个数组 需要指定