C++中的数组

在C++中,数组是存储固定大小同类型元素的连续内存块。它是最基础的数据结构之一,广泛用于各种场景。以下是关于数组的详细介绍:

一、一维数组

1. 定义与初始化
  • 语法类型 数组名[元素个数];
  • 示例
    int arr[5];  // 定义包含5个整数的数组
    arr[0] = 10;  // 赋值
    arr[1] = 20;// 初始化列表
    int arr2[5] = {1, 2, 3, 4, 5};  // 完整初始化
    int arr3[] = {10, 20, 30};      // 自动推导长度为3
    int arr4[5] = {1, 2};           // 部分初始化,剩余元素为0
    
2. 访问与遍历
  • 下标访问:索引从0开始,范围为0长度-1
    int value = arr[2];  // 访问第3个元素
    arr[3] = 40;         // 修改第4个元素
    
  • 遍历方式
    // 传统for循环
    for (int i = 0; i < 5; i++) {cout << arr[i] << " ";
    }// 范围for循环(C++11起)
    for (int num : arr) {cout << num << " ";
    }
    

二、多维数组

1. 二维数组
  • 定义类型 数组名[行数][列数];
  • 示例
    int matrix[2][3] = {{1, 2, 3},{4, 5, 6}
    };// 访问元素
    int value = matrix[1][2];  // 第二行第三列(值为6)
    
2. 多维数组内存布局
  • 连续存储:多维数组在内存中按行优先(Row-major)存储,例如:
    int arr[2][2] = {{1, 2}, {3, 4}};
    // 内存布局:1, 2, 3, 4
    

三、数组与指针

1. 数组名隐式转换为指针
  • 数组名在多数表达式中会隐式转换为指向首元素的指针:
    int arr[5] = {1, 2, 3, 4, 5};
    int* ptr = arr;  // 等价于 &arr[0]// 通过指针访问数组
    cout << *ptr;    // 输出1
    cout << *(ptr+2);  // 输出3(等价于 arr[2])
    
2. 指针算术
  • 指针加减运算基于元素类型大小:
    int* p = arr;
    p++;  // 指针移动4字节(int类型大小)
    
3. 动态数组(使用指针)
  • 堆上分配:使用newdelete[]
    int size = 10;
    int* dynamicArr = new int[size];  // 动态分配数组// 使用数组
    for (int i = 0; i < size; i++) {dynamicArr[i] = i;
    }delete[] dynamicArr;  // 释放内存
    

四、数组作为函数参数

1. 数组退化问题
  • 数组作为参数时会退化为指针,丢失大小信息:
    void printArray(int arr[]) {  // 等价于 int* arr// sizeof(arr) 返回指针大小(如8字节),非数组大小
    }
    
2. 正确传递数组的方法
  • 显式传递大小
    void printArray(int arr[], int size) {for (int i = 0; i < size; i++) {cout << arr[i] << " ";}
    }
    
  • 使用引用:保留数组大小信息:
    void printArray(int (&arr)[5]) {  // 仅接受长度为5的数组for (int num : arr) {cout << num << " ";}
    }
    
  • 使用模板:自动推导大小:
    template <size_t N>
    void printArray(int (&arr)[N]) {for (int num : arr) {cout << num << " ";}
    }
    

五、C++标准库替代方案

1. std::array(C++11起)
  • 特点:固定大小数组,封装在类中,提供更安全的接口。
  • 示例
    #include <array>std::array<int, 5> arr = {1, 2, 3, 4, 5};// 安全特性
    cout << arr.size();  // 返回5
    // arr[10] = 0;  // 越界访问(运行时可能崩溃)
    arr.at(10) = 0;  // 越界访问(抛出std::out_of_range异常)
    
2. std::vector
  • 特点:动态数组,支持自动扩容。
  • 示例
    #include <vector>std::vector<int> vec = {1, 2, 3};
    vec.push_back(4);  // 动态添加元素
    cout << vec.size();  // 返回4
    

六、常见陷阱与最佳实践

1. 数组越界访问
  • 问题:访问超出数组边界的元素,导致未定义行为。
  • 示例
    int arr[3] = {1, 2, 3};
    cout << arr[3];  // 越界访问,可能崩溃或读取随机值
    
2. 内存泄漏(动态数组)
  • 问题:忘记释放new分配的内存。
  • 解决方案:优先使用std::vector或智能指针:
    #include <memory>// 使用智能指针管理动态数组
    std::unique_ptr<int[]> arr(new int[10]);
    
3. 避免C风格数组
  • 建议:优先使用std::arraystd::vector替代原始数组,减少手动内存管理:
    // 推荐写法
    std::array<int, 5> arr;  // 固定大小
    std::vector<int> vec;    // 动态大小
    

通过合理使用数组和标准库容器,你能高效处理各种数据存储需求。建议优先使用std::vectorstd::array,仅在性能敏感或与C代码交互时使用原始数组。

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

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

相关文章

three.js 零基础到入门

three.js 零基础到入门 什么是 three.js为什么使用 three.js使用 Three.js1. 创建场景示例 2.创建相机3. 创建立方体并添加网格地面示例 5. 创建渲染器示例 6. 添加效果(移动/雾/相机跟随物体/背景)自动旋转示例效果 相机自动旋转示例 展示效果 实现由远到近的雾示例展示效果 T…

Elasticsearch的写入性能优化

优化Elasticsearch的写入性能需要从多维度入手,包括集群配置、索引设计、数据处理流程和硬件资源等。以下是一些关键优化策略和最佳实践: 一、索引配置优化 合理设置分片数与副本数分片数(Shards):过少会导致写入瓶颈(无法并行),过多会增加集群管理开销。公式参考:分…

FMC STM32H7 SDRAM

如何无痛使用片外SDRAM? stm32 已经成功初始化了 STM32H7 上的外部 SDRAM&#xff08;32MB&#xff09; 如何在开发中无痛使用SDRAM 使它像普通 RAM 一样“自然地”使用? [todo] 重要 MMT(Memory Management Tool) of STM32CubeMx The Memory Management Tool (MMT) disp…

【AIGC】RAGAS评估原理及实践

【AIGC】RAGAS评估原理及实践 &#xff08;1&#xff09;准备评估数据集&#xff08;2&#xff09;开始评估2.1 加载数据集2.2 评估忠实性2.3 评估答案相关性2.4 上下文精度2.5 上下文召回率2.6 计算上下文实体召回率 RAGas&#xff08;RAG Assessment)RAG 评估的缩写&#xff…

VuePress完美整合Toast消息提示

VuePress 整合 Vue-Toastification 插件笔记 记录如何在 VuePress 项目中整合使用 vue-toastification 插件&#xff0c;实现优雅的消息提示。 一、安装依赖 npm install vue-toastification或者使用 yarn&#xff1a; yarn add vue-toastification二、配置 VuePress 客户端增…

C#学习12——预处理

一、预处理指令&#xff1a; 解释&#xff1a;是在编译前由预处理器执行的命令&#xff0c;用于控制编译过程。这些命令以 # 开头&#xff0c;每行只能有一个预处理指令&#xff0c;且不能包含在方法或类中。 个人理解&#xff1a;就是游戏里面的备战阶段&#xff08;不同对局…

开疆智能Profinet转Profibus网关连接CMDF5-8ADe分布式IO配置案例

本案例是客户通过开疆智能研发的Profinet转Profibus网关将PLC的Profinet协议数据转换成IO使用的Profibus协议&#xff0c;操作步骤如下。 配置过程&#xff1a; Profinet一侧设置 1. 打开西门子组态软件进行组态&#xff0c;导入网关在Profinet一侧的GSD文件。 2. 新建项目并…

(三)Linux性能优化-CPU-CPU 使用率

CPU使用率 user&#xff08;通常缩写为 us&#xff09;&#xff0c;代表用户态 CPU 时间。注意&#xff0c;它不包括下面的 nice 时间&#xff0c;但包括了 guest 时间。nice&#xff08;通常缩写为 ni&#xff09;&#xff0c;代表低优先级用户态 CPU 时间&#xff0c;也就是进…

Digital IC Design Flow

Flow介绍 1.设计规格 架构师根据市场需求制作算法模型(Algorithm emulation)及芯片架构(Chip architecture),确定芯片设计规格书(Chip design specification) 原型验证 原型验证(Prototype Validation)通常位于产品开发流程的前期阶段,主要是在设计和开发的初步阶…

算法打卡第18天

从中序与后序遍历序列构造二叉树 (力扣106题) 给定两个整数数组 inorder 和 postorder &#xff0c;其中 inorder 是二叉树的中序遍历&#xff0c; postorder 是同一棵树的后序遍历&#xff0c;请你构造并返回这颗 二叉树 。 示例 1: 输入&#xff1a;inorder [9,3,15,20,7…

LangChain工具集成实战:构建智能问答系统完整指南

导读&#xff1a;在人工智能快速发展的今天&#xff0c;如何构建一个既能理解自然语言又能调用外部工具的智能问答系统&#xff0c;成为许多开发者面临的核心挑战。本文将为您提供一套完整的解决方案&#xff0c;从LangChain内置工具包的基础架构到复杂系统的工程实践。 文章深…

P3156 【深基15.例1】询问学号

P3156 【深基15.例1】询问学号 - 洛谷 数据结构-线性表 #include<bits/stdc.h> using namespace std; int n,m,a[2000005]; int main(){cin>>n>>m;for(int i1;i<n;i)cin>>a[i];//使用数组模拟线性表while(m--){int k;cin>>k;cout<<a[…

衡量嵌入向量的相似性的方法

衡量嵌入向量的相似性的方法 一、常见相似性计算方法对比 方法核心原理公式优点缺点适用场景余弦相似度计算向量夹角的余弦值,衡量方向相似性,与向量长度无关。$\text{cos}\theta = \frac{\mathbf{a} \cdot \mathbf{b}}{\mathbf{a}\mathbf{b}欧氏距离计算向量空间中的直线距离…

小番茄C盘清理:专业高效的电脑磁盘清理工具

在使用电脑的过程中&#xff0c;我们常常会遇到系统盘空间不足、磁盘碎片过多、垃圾文件堆积等问题&#xff0c;这些问题不仅会导致电脑运行缓慢&#xff0c;还可能引发系统崩溃。为了解决这些问题&#xff0c;小番茄C盘清理应运而生。它是一款专业的C盘清理软件&#xff0c;能…

【版本控制】Git 和 GitHub 入门教程

目录 0 引言1 Git与GitHub的诞生1.1 Git&#xff1a;Linus的“两周奇迹”&#xff0c;拯救Linux内核1.2 GitHub&#xff1a;为Git插上协作的翅膀1.3 协同进化&#xff1a;从工具到生态的质变1.4 关键历程时间轴&#xff08;2005–2008&#xff09; 2 Git与GitHub入门指南2.1 Gi…

Dify源码教程:账户和密码传递分析

概述 Dify系统中账户创建过程中的密码处理是Web应用安全的重要环节。本教程详细分析了从前端表单到后端存储的完整流程&#xff0c;展示了Dify如何安全地处理用户凭据。 前端部分 在 dify/web/app/install/installForm.tsx 文件中&#xff0c;当用户填写完表单并点击安装按钮…

window查看SVN账号密码

背景 公司的SVN地址发生迁移&#xff0c;想迁移一下本地SVN地址&#xff0c;后来发现SVN账号密码忘记了。写此文章纯记录。 迁移SVN地址&#xff1a; 找到svn目录点击relocate&#xff0c;输入新的svn地址&#xff0c;如需输入账号密码&#xff0c;输入账号密码即完成svn地址…

Read View在MVCC里如何工作

Read View的结构 Read View中有四个重要的字段&#xff1a; m_ids&#xff1a;创建 Read View 时&#xff0c;数据库中启动但未提交的「活跃事务」的事务 id 列表 。min_trx_id&#xff1a;创建 Read View 时&#xff0c;「活跃事务」中事务 id 最小的值&#xff0c;即 m_ids …

如何在mac上安装podman

安装 Podman 在 macOS 上 在 macOS 上安装 Podman 需要使用 Podman 的桌面客户端工具 Podman Desktop 或通过 Homebrew 安装命令行工具。 使用 Homebrew 安装 Podman&#xff1a; (base) ninjamacninjamacdeMacBook-Air shell % brew install podman > Auto-updating Hom…

QGraphicsView中鼠标点击与移动事件传递给MainWindow

在Qt图形应用程序开发中,QGraphicsView和QGraphicsScene框架提供了强大的2D图形显示功能。然而,当我们需要在主窗口(MainWindow)中处理这些视图中的鼠标事件。 问题背景 在典型的Qt图形应用程序架构中: MainWindow └── QGraphicsView└── QGraphicsScene└── QGra…