当前位置: 首页 > news >正文

C++数组与字符串:从基础到实战技巧

C++中的数组和字符串是处理数据集合和文本的基础工具。数组用于存储相同类型的元素集合,而字符串则专门用于处理文本数据。C++提供了两种主要的字符串处理方式:C风格字符串(字符数组)和C++的std::string类。

📊 1. 数组 (Arrays)

数组是相同类型元素的集合,这些元素在内存中连续存储。数组的大小在定义时确定,且不能改变。

一维数组

  • 声明与初始化

    数组的声明需要指定元素类型、数组名和大小。初始化可以在声明时进行。

    int numbers[5];// 声明一个包含5个整数的数组,未初始化int numbers[5] = {1, 2, 3, 4, 5};// 声明并初始化int numbers[] = {1, 2, 3, 4, 5};// 编译器自动计算大小

    如果初始化值少于数组元素,剩余元素会自动初始化为0(对于基本数据类型)

  • 访问元素

    通过索引访问数组元素,索引从0开始。

    int first = numbers[0];// 访问第一个元素
    numbers[4] = 10;// 修改第五个元素
  • 特点

    • 内存连续,访问高效。
    • 大小固定,无法动态扩容。
    • 需注意数组越界访问,这可能引发未定义行为。

多维数组

多维数组,如二维数组,可视为“数组的数组”,常用于表示矩阵或表格。

  • 声明与初始化

    int matrix[2][3] = {{1, 2, 3}, {4, 5, 6}};// 2行3列int matrix[2][3] = {1, 2, 3, 4, 5, 6};// 按顺序初始化
  • 访问元素

    使用多个索引访问元素。

    int value = matrix[1][2];// 访问第二行第三列(值为6)

动态数组

使用newdelete[]在堆上动态分配和释放内存。

int size = 5;
int* dynamicArray = new int[size];// 动态分配// 使用 dynamicArray...delete[] dynamicArray;// 释放内存

动态数组需手动管理内存,防止内存泄漏。

🔤 2. 字符串 (Strings)

C++中有两种主要的字符串表示方式:C风格字符串和std::string类。

C风格字符串 (C-Style Strings)

C风格字符串本质是以空字符'\0'结尾的字符数组

  • 声明与初始化

    char str1[] = "Hello";// 编译器自动添加'\0',数组长度为6char str2[6] = {'H', 'e', 'l', 'l', 'o', '\0'};// 手动添加终止符

    字符串字面量用双引号括起,编译器会自动在其末尾添加空字符

  • 常用函数

    使用C标准库函数(需包含<cstring>)进行操作:

    #include <cstring>char str1[20] = "Hello";
    char str2[] = "World";strlen(str1);// 获取字符串长度(不包括'\0')strcpy(str1, str2);// 复制字符串(需确保目标空间足够)strcat(str1, "!");// 连接字符串(需确保目标空间足够)strcmp(str1, "Hello World!");// 比较字符串(相等返回0)

    注意:使用strcpystrcat等函数时,必须确保目标字符数组有足够的空间,否则可能导致缓冲区溢出

std::string类

C++标准库提供的std::string类(需包含<string>头文件)封装了字符串操作,自动管理内存,更安全便捷

  • 声明与初始化

    #include <string>
    std::string s1;// 空字符串
    std::string s2 = "Hello, World!";// 初始化std::string s3(s2);// 拷贝构造
  • 常用操作

    std::string支持丰富的操作:

    s1 = "Hello"; s2 = "World";
    std::string s4 = s1 + ", " + s2;// 字符串拼接(使用+运算符)
    s1.append(" World!");// 追加字符串int len = s1.length();// 或 s1.size(),获取字符串长度char ch = s1[0];// 通过索引访问字符(不检查边界)
    ch = s1.at(0);// 使用at()访问(会检查边界,越界抛出异常)std::string sub = s1.substr(7, 5);// 提取子串(从位置7开始,长度为5)size_t pos = s1.find("World");// 查找子串,返回首次出现的位置(未找到返回std::string::npos)
    s1.replace(7, 5, "C++");// 替换子串(从位置7开始,替换5个字符为"C++")
    s1.insert(7, "Beautiful ");// 插入字符串
    s1.erase(7, 10);// 删除子串(从位置7开始,删除10个字符)if (s1 == s2) {/* 比较字符串 */ }// 支持关系运算符比较
  • 输入输出

    使用getline读取整行文本(包括空格):

    std::string name;
    std::cout << "Enter your full name: ";
    std::getline(std::cin, name);// 读取整行
    std::cout << "Hello, " << name << std::endl;

    使用cin进行输入时,遇到空格、制表符或换行符会停止读取

转换

  • std::string与 C风格字符串互转

    std::string s = "Hello";
    const char* cstr1 = s.c_str();// 转换为C风格字符串(只读,指向s的内部数据)const char* cstr2 = s.data();// C++17前与c_str()类似,C++17起可能不以空字符结尾char arr[20];
    std::strcpy(arr, s.c_str());// 将s的内容复制到可修改的字符数组arr中const char* cstr = "World";
    std::string s_from_c = cstr;// C风格字符串转换为std::string

    注意:c_str()返回的指针在std::string对象发生修改后可能失效

⚖️ 3. 对比与选择

特性C风格字符串std::string
内存管理手动管理,易出错自动管理,避免泄漏
安全性易缓冲区溢出/越界更安全,边界检查
功能基础函数(strlen, strcpy等)丰富方法(拼接、查找、替换等)
性能开销小,适合底层或嵌入式动态扩容可能带来开销,但通常更便捷

建议:在现代C++开发中,优先使用std::string,除非在与C代码交互或对性能有极端要求的场景下才考虑使用C风格字符串

💡 4. 注意事项

  1. 数组越界:访问数组时,确保索引在[0, size-1]范围内,越界访问会导致未定义行为。
  2. 字符串结束符:操作C风格字符串时,务必确保其以'\0'结尾,否则相关字符串函数可能无法正常工作甚至导致程序崩溃。
  3. 空间充足:对C风格字符串进行拼接、复制等操作前,务必确认目标字符数组有足够的空间,防止缓冲区溢出。
  4. std::stringc_str():不要存储c_str()返回的指针并在后续修改std::string对象,除非已重新获取。该指针指向的数据可能在std::string修改后失效。

掌握数组和字符串的基础知识是进行有效C++开发的关键。根据具体场景选择合适的工具,并始终牢记安全操作的准则。


文章转载自:

http://YQvg0HYQ.yrrnx.cn
http://CHqXJJ8T.yrrnx.cn
http://olUQD7Ty.yrrnx.cn
http://5WHd0dcO.yrrnx.cn
http://3mZPpZ0F.yrrnx.cn
http://BC5UBb2L.yrrnx.cn
http://iRfE5LZg.yrrnx.cn
http://ygX6mPfb.yrrnx.cn
http://CRbEEiY0.yrrnx.cn
http://MQxih2JT.yrrnx.cn
http://Dw6JAynQ.yrrnx.cn
http://dZWKbaUK.yrrnx.cn
http://Sh597lrX.yrrnx.cn
http://XeOpd50m.yrrnx.cn
http://vg53kq22.yrrnx.cn
http://PDntcGTX.yrrnx.cn
http://e9PC89oq.yrrnx.cn
http://Kylc8S8p.yrrnx.cn
http://GhZAEiOQ.yrrnx.cn
http://pZAvNaCL.yrrnx.cn
http://DEXzgmDm.yrrnx.cn
http://ibmtqgpq.yrrnx.cn
http://ZNCEbLOC.yrrnx.cn
http://Ec2UtxNh.yrrnx.cn
http://19l7zb5X.yrrnx.cn
http://M1ZQ6ITm.yrrnx.cn
http://eaBYaDTn.yrrnx.cn
http://XyFvKnzs.yrrnx.cn
http://Kkx3u5EJ.yrrnx.cn
http://TCXDznm1.yrrnx.cn
http://www.dtcms.com/a/382838.html

相关文章:

  • 第13课:分布式Agent系统
  • Docker 容器化部署核心实战——Nginx 服务配置与正反向代理原理解析
  • 【分享】中小学教材课本 PDF 资源获取指南
  • 如何用 Git Hook 和 CI 流水线为 FastAPI 项目保驾护航?
  • 安卓旋转屏幕后如何防止数据丢失-ViewModel入门
  • STM32_05_时钟树
  • 元宇宙与体育产业:沉浸式体验重构体育全链条生态
  • LeetCode 每日一题 966. 元音拼写检查器
  • C++密码锁 2023年CSP-S认证真题 CCF信息学奥赛C++ 中小学提高组 第二轮真题解析
  • Vue3 视频播放器完整指南 – @videojs-player/vue 从入门到精通
  • 零售企业数字化转型的道、法、术:基于开源AI大模型AI智能名片S2B2C商城小程序的战略重构
  • 【编号500】(道路分类)广东路网数据广东路网分类数据(2025年)
  • 【PHP7内核剖析】-1.3 FPM
  • 网络编程之UDP广播与粘包问题
  • h3笔记:polygon
  • Unity 性能优化 之 编辑器创建资源优化( 工作流 | 场景 | 预制体)
  • 《Python Web部署应知应会》No3:Flask网站的性能优化和实时监测深度实战
  • 《嵌入式硬件(十):基于IMX6ULL的按键操作》
  • JVM默认栈大小
  • 深度学习实战指南:从神经网络基础到模型优化的完整攻略
  • 浏览器性能测试深度解析:指标、工具与优化实践
  • 【嵌入式DIY实例-ESP32篇】-3D姿态测量(Pitch, Roll, Yaw)
  • LeetCode 0966.元音拼写检查器:三个哈希表实现
  • 深入浅出 HarmonyOS 应用开发:ArkTS 声明式 UI 与状态管理最佳实践
  • 大数据处理与清洗实战:从Spark到Flink的深度优化
  • 从零开始搞定C++类和对象:取地址运算符重载
  • 第8课:Agent协作模式实现
  • 【LeetCode 每日一题】3021. Alice 和 Bob 玩鲜花游戏
  • Zulu - 百度文心快码推出的自动编程智能体
  • AI学习工具三剑客:NotebookLM、Gemini Guided Learning与ChatGPT Study深度对比