C++从入门到实战(十五)String(上)介绍STL与String的关系,为什么有string类,String有什么用

06-02 1038阅读

C++从入门到实战(十五)String(上)

  • 前言
  • 一、STL与String的关系
    • 1. STL 是什么?
    • 2. String 是什么?
    • 3. String 与 STL 的关系
    • 二、为什么有string类,有什么用
      • 1. 为什么需要 string 类?
      • 2. string 类的核心作用:
      • 3. string 类的其他能力:(后面会详细讲,现在看一下就好)
      • 4. 和 C风格字符串对比
      • 三、auto和范围for
        • 1. auto 关键字:
          • 1.1 基本用法
          • 1.2 细节注意
          • 1.3 与Python的对比
          • 2. 范围for循环:
            • 2.1 基本语法
            • 2.2 修改元素:用引用
            • 3. 适用范围
              • (1)适用场景
                • 1. STL容器(如 vector、list、map 等)
                • 2. 普通数组(静态/动态)
                • 3. 字符串(`std::string` 或 C风格字符串)
                • 4. 初始化列表(临时构造的集合)
                • (2)不适用场景(了解就好)
                  • 1. 需要索引时
                  • 2. 动态修改容器大小
                  • 3. 通过指针访问的数组
                  • 4. 不支持迭代器的自定义类型
                  • (3)关键细节
                    • 1. 修改元素:用引用 &
                    • 2. 避免拷贝:用 const auto&
                    • 3. 底层原理

                      前言

                      • 在前面的博客中,我们已经探讨了 C++ 的类和对象、内存管理、模板等重要概念。
                      • 从本篇开始,我们将进入 C++ 的另一个重要阶段 —— 标准模板库(STL)的学习。STL 是 C++ 强大的工具集,它提供了各种容器、算法和迭代器,极大地提高了代码的复用性和开发效率。
                      • 在上一篇博客中,我们介绍了 STL 的基本概念和组成部分。这篇博客,我们将着重介绍STL与String的关系,为什么有string类,String有什么用。

                        我的个人主页,欢迎来阅读我的其他文章

                        https://blog.csdn.net/2402_83322742?spm=1011.2415.3001.5343

                        我的C++知识文章专栏

                        欢迎来阅读指出不足

                        https://blog.csdn.net/2402_83322742/category_12880513.html?spm=1001.2014.3001.5482


                        一、STL与String的关系

                        一句话总结:string是 STL 提供的、专门用来高效处理字符串的 “容器类”,既具备 STL 容器的通用特性(迭代器、动态内存等),又针对字符串操作做了专属优化

                        C++从入门到实战(十五)String(上)介绍STL与String的关系,为什么有string类,String有什么用

                        1. STL 是什么?

                        STL是C++标准库的核心组件,提供了一套通用的模板类和函数,用于处理各种数据结构(如数组、链表、栈、队列等)和算法(如排序、查找等)。

                        类比:STL就像一个“工具箱”,里面有各种“工具”(容器、算法、迭代器等),可以直接拿来用。

                        2. String 是什么?

                        • String是STL中的一个容器类,专门用于处理字符串(文本数据)。它封装了字符数组,提供了更方便的操作方法(如拼接、查找、替换等)。
                        • 类比:String就像“工具箱”里的“螺丝刀”,是专门用来拧螺丝(处理字符串)的工具。

                          3. String 与 STL 的关系

                          • String 是 STL 容器的一种:STL包含多种容器(如vector、list、map),而string是其中专门处理文本的容器。
                          • 共享 STL 的特性:
                            • 动态管理内存:无需手动分配/释放内存,如string s = "hello";。
                            • 支持迭代器:可以像遍历数组一样遍历字符串(如s.begin()、s.end())。
                            • 丰富的方法:如s.length()、s.substr()、s.find()等。

                              二、为什么有string类,有什么用

                              1. 为什么需要 string 类?

                              生活场景:

                              假设你是老师,要记录学生的姓名。如果没有 string,你得用 C风格字符数组(像用便签纸记录):

                              char name[100];  // 必须提前指定最大长度(比如最多100个字符)
                              

                              但现实中,名字长度不一(有人叫"张三",有人叫"阿卜杜勒·拉赫曼"),用固定长度的数组会遇到两个问题:

                              • 问题1:长度不够(比如名字超过100个字符),数组会越界(像便签纸写不下,字会挤到外面)。
                              • 问题2:长度浪费(比如名字只有3个字符,却占了100个位置)。

                                而 string 类就像一个自动伸缩的便签纸,你写多少字,它就自动扩展多长,完美解决上述问题!

                                2. string 类的核心作用:

                                #include   // 使用string必须包含这个头文件
                                std::string name = "阿卜杜勒·拉赫曼";  // 无需指定长度,自动适应内容
                                
                                • 优势1:无需关心内存大小,随便存多长的字符串。
                                • 优势2:无需手动释放内存,用起来更安全(不会忘记释放导致内存泄漏)。

                                  3. string 类的其他能力:(后面会详细讲,现在看一下就好)

                                  生活场景:

                                  假设你要给学生分组,需要把姓和名拼起来(比如"张" + “三” → “张三”),或者判断名字是否包含"小"字。

                                  用 string 类,这些操作就像玩积木一样简单:

                                  std::string first = "张";
                                  std::string last = "三";
                                  // 1. 拼接字符串(积木拼接)
                                  std::string fullName = first + last;  // "张三"
                                  // 2. 获取长度(量积木长度)
                                  int len = fullName.length();  // 2
                                  // 3. 判断是否包含子串(找积木中的特定小块)
                                  bool hasXiao = fullName.find("小") != std::string::npos;  // false
                                  // 4. 替换部分内容(替换积木的某一块)
                                  fullName.replace(0, 1, "李");  // "张三" → "李三"
                                  // 5. 截取子串(从积木中拆出一部分)
                                  std::string sub = fullName.substr(0, 1);  // "李"
                                  

                                  4. 和 C风格字符串对比

                                  操作C风格字符数组 (char[])C++ string 类
                                  初始化char name[10] = "张三";std::string name = "张三";
                                  拼接strcat(name, "三");(需确保数组足够大)name += "三";(自动扩展)
                                  获取长度strlen(name);(需遍历数组)name.length();(O(1) 时间复杂度)
                                  复制strcpy(dest, src);(需手动管理内存)dest = src;(自动处理)
                                  安全性容易越界,导致程序崩溃自动管理内存,不会越界

                                  总结

                                  • 自动伸缩:不用操心内存大小,随便存多长的内容。

                                  • 操作简单:拼接、查找、替换等功能直接用,像搭积木一样方便。

                                  • 安全可靠:不会越界,不会忘记释放内存,程序更稳定。

                                  • 以后写代码遇到字符串,直接用 string!除非特殊场景(如性能要求极高、和C语言交互),否则完全不需要用 char[]。

                                    三、auto和范围for

                                    在正式开始之前我们需要详细讲解auto和范围for,以帮助我们后续的理解string

                                    1. auto 关键字:

                                    生活场景:

                                    假设你是餐厅服务员,客人点了一杯“饮料”(没说具体是什么)。你不用纠结,直接根据客人的语气和场景猜:

                                    • 如果客人说“来杯冰的!” → 可能是“冰可乐”。
                                    • 如果客人说“要热的!” → 可能是“热茶”。

                                      auto 就像这个“猜饮料”的过程,让编译器根据右边的值自动推导变量的类型。

                                      1.1 基本用法

                                      auto num = 42;       // 编译器猜:int
                                      auto pi = 3.14;      // 编译器猜:double
                                      auto name = "Alice"; // 编译器猜:const char*
                                      

                                      优势:

                                      • 代码更简洁,不用写冗长的类型名(比如 std::vector::iterator)。
                                      • 避免手动写错类型。

                                        1.2 细节注意

                                        • 指针与引用:

                                          int x = 10;
                                          auto ptr = &x;     // auto 推导为 int*(auto* 也可以,但没必要)
                                          auto& ref = x;     // 必须加 &,否则 ref 会是 int(复制值)
                                          
                                        • 同一行声明多个变量:

                                          auto a = 1, b = 2;     // 正确:都是 int
                                          auto c = 3, d = 3.14;  // 错误:c 是 int,d 是 double
                                          
                                        • 不能做函数参数:

                                          void func(auto x) { }  // 错误:编译器无法推导参数类型
                                          

                                          1.3 与Python的对比

                                          特性C++ autoPython 变量
                                          类型推导时机编译时(静态类型)运行时(动态类型)
                                          类型是否固定一旦推导,类型固定运行中可以改变
                                          示例auto x = 1; x = "hello"; // 错误x = 1; x = "hello"; // 正确

                                          2. 范围for循环:

                                          生活场景:

                                          假设你要挨个检查教室里的桌子,传统写法是:

                                          1. 从第一张桌子开始(初始化)。
                                          2. 检查当前桌子,然后走到下一张(迭代)。
                                          3. 直到走完所有桌子(终止条件)。

                                          而范围for循环就像:“你直接说‘检查所有桌子’,系统自动帮你挨个检查,不用操心细节”。

                                          2.1 基本语法

                                           // 字符串数组
                                              std::string words[3] = {"apple", "banana", "cherry"};
                                              
                                              // 传统for循环
                                              std::cout 
                                                  std::cout 
                                                  std::cout 
                                                  word += "!";  // 给每个字符串添加感叹号
                                              }
                                              
                                              // 输出修改后的字符串
                                              for (const auto& word : words) 
                                              {
                                                  std::cout 
                                              // 遍历 vector
                                              std::vector1, 2, 3};
                                              for (auto num : nums) {  // 自动推导为 int
                                                  std::cout {"Alice", 90}, {"Bob", 85}};
                                              for (const auto& pair : scores) {  // pair 是 std::pair1, 2, 3};
                                          for (auto x : arr) { ... }
                                          // 动态数组(通过指针访问时**不适用**,见下文注意事项)
                                          int* dyn_arr = new int[3]{1, 2, 3};
                                          // for (auto x : dyn_arr) { ... }  // 错误!无法推导数组大小
                                            // 遍历每个字符
                                              std::cout  ... }  // 需要转为 std::string
                                          1, 3, 5, 7}) {  // 直接遍历花括号初始化列表
                                              std::cout 1, 2, 3};
                                          for (auto& num : nums) {  // 引用传递,修改原数组
                                              num *= 2;
                                          }
                                            // 避免拷贝 string
                                              ...
                                          }
                                          
                                              auto element = *it;  // 自动解引用
                                          }
                                          
免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们。

相关阅读

目录[+]

取消
微信二维码
微信二维码
支付宝二维码