C++ STL 核心:string 从入门到精通(面试+源码+OJ实战)

C++ STL 核心:string 从入门到精通(面试+源码+OJ实战)

标签 :C++、STL、string、C++面试、C++基础、后端开发
摘要:本文全面讲解 C++ string 类,包含使用方法、遍历技巧、容量操作、VS/GCC 底层结构、深浅拷贝、写时拷贝、string 模拟实现与高频 OJ 题,适合面试备战与工程开发。


文章目录

  • [C++ STL 核心:string 从入门到精通(面试+源码+OJ实战)](#C++ STL 核心:string 从入门到精通(面试+源码+OJ实战))
    • [0 前言](#0 前言)
    • [1 为什么要学 string?](#1 为什么要学 string?)
      • [1.1 C 语言字符串的痛点](#1.1 C 语言字符串的痛点)
      • [1.2 现实需求](#1.2 现实需求)
    • [2 使用 string 的前置准备](#2 使用 string 的前置准备)
    • [3 C++11 神器:auto + 范围 for(string 遍历必备)](#3 C++11 神器:auto + 范围 for(string 遍历必备))
      • [3.1 auto 类型推导](#3.1 auto 类型推导)
      • [3.2 范围 for(最简洁遍历)](#3.2 范围 for(最简洁遍历))
    • [4 string 核心接口(高频必背)](#4 string 核心接口(高频必背))
      • [4.1 构造函数(4 个重点)](#4.1 构造函数(4 个重点))
      • [4.2 容量操作(面试必考)](#4.2 容量操作(面试必考))
      • [4.3 遍历三剑客](#4.3 遍历三剑客)
      • [4.4 修改与查找(开发最常用)](#4.4 修改与查找(开发最常用))
      • [4.5 输入神器:getline](#4.5 输入神器:getline)
    • [5 string 底层结构(面试高频)](#5 string 底层结构(面试高频))
      • [5.1 VS 下:SSO 短字符串优化](#5.1 VS 下:SSO 短字符串优化)
      • [5.2 GCC 下:COW 写时拷贝](#5.2 GCC 下:COW 写时拷贝)
    • [6 面试必问:浅拷贝 vs 深拷贝](#6 面试必问:浅拷贝 vs 深拷贝)
      • [6.1 浅拷贝(坑)](#6.1 浅拷贝(坑))
      • [6.2 深拷贝(解决方案)](#6.2 深拷贝(解决方案))
      • [6.3 现代写法(最优)](#6.3 现代写法(最优))
      • [6.4 写时拷贝 COW](#6.4 写时拷贝 COW)
    • [7 string 模拟实现(面试可直接手写)](#7 string 模拟实现(面试可直接手写))
    • [8 OJ 实战:string 高频题(带答案)](#8 OJ 实战:string 高频题(带答案))
      • [8.1 仅仅反转字母](#8.1 仅仅反转字母)
      • [8.2 第一个只出现一次的字符](#8.2 第一个只出现一次的字符)
      • [8.3 字符串相加(大数加法)](#8.3 字符串相加(大数加法))
    • [9 string 核心要点总结(背会直接面试)](#9 string 核心要点总结(背会直接面试))
    • [10 结尾 & 引流](#10 结尾 & 引流)

0 前言

不懂 string,别说你会用 C++。

string 是 STL 最基础、最常用、面试最高频的组件,没有之一。它解决了 C 语言字符串手动管理内存、接口零散、容易越界的痛点,是日常开发与笔试 OJ 的必备工具。

这篇文章带你从会用 → 懂原理 → 能手写 → 能面试,一次性吃透 string。


1 为什么要学 string?

1.1 C 语言字符串的痛点

  • \0 结尾,内存必须自己管理,一不小心就越界、泄漏。
  • str 系列函数与字符串分离,不符合 OOP 思想。
  • 拼接、查找、扩容、比较都很麻烦。

1.2 现实需求

  • OJ 字符串题默认用 string
  • 工作开发几乎不用 C 风格字符串。
  • 面试必考:深浅拷贝、扩容、底层结构、c_str、迭代器失效。

2 使用 string 的前置准备

cpp 复制代码
#include <string>
using namespace std;

3 C++11 神器:auto + 范围 for(string 遍历必备)

3.1 auto 类型推导

  • 编译期自动推导类型,简化迭代器。
  • 必须初始化。
  • 不能做函数参数,不能定义数组。
  • 定义引用必须加 &。
cpp 复制代码
auto a = 10;        // int
auto p = &a;        // int*
auto& r = a;        // int&

3.2 范围 for(最简洁遍历)

底层就是迭代器,自动遍历、自动结束。

cpp 复制代码
string s = "hello";
for (auto& ch : s) {  // 加 & 可修改
    ch = toupper(ch);
}
for (auto ch : s) {   // 只读
    cout << ch << " ";
}

4 string 核心接口(高频必背)

4.1 构造函数(4 个重点)

cpp 复制代码
string s1;                  // 空串
string s2("hello");         // C 字符串构造
string s3(5, 'a');          // n 个字符
string s4(s2);              // 拷贝构造

4.2 容量操作(面试必考)

接口 作用
size() / length() 有效字符长度
capacity() 底层容量
empty() 是否为空
clear() 清空有效字符,不缩容
reserve(n) 预分配空间,不改 size
resize(n, c) 改有效长度,多出来用 c 填充

一句话区分

  • reserve:只扩容,不改长度
  • resize:改长度,会初始化

4.3 遍历三剑客

  1. 下标 []
cpp 复制代码
for (int i = 0; i < s.size(); ++i)
    cout << s[i];
  1. 迭代器
cpp 复制代码
string::iterator it = s.begin();
while (it != s.end()) {
    cout << *it;
    ++it;
}
  1. 范围 for(C++11 首选)
cpp 复制代码
for (auto ch : s) cout << ch;

4.4 修改与查找(开发最常用)

cpp 复制代码
s += "hello";        // 拼接(优先用)
s += ' ';
s.append("world");
const char* cstr = s.c_str();  // 转 C 字符串

size_t pos = s.find('w');      // 查找
string sub = s.substr(0,5);    // 截取

4.5 输入神器:getline

读取带空格的一整行:

cpp 复制代码
string line;
getline(cin, line);

5 string 底层结构(面试高频)

5.1 VS 下:SSO 短字符串优化

  • 32 位占 28 字节
  • 长度 < 16:内部栈数组
  • 长度 ≥ 16:堆空间
  • 结构:联合体 + size + capacity + 指针

5.2 GCC 下:COW 写时拷贝

  • 只占 4 字节(一个指针)
  • 堆内存存:长度 + 容量 + 引用计数
  • 读共享、写复制,高效省内存

6 面试必问:浅拷贝 vs 深拷贝

6.1 浅拷贝(坑)

  • 默认拷贝构造只拷贝指针。
  • 多个对象共用同一块内存
  • 析构时重复释放 → 程序崩溃。

6.2 深拷贝(解决方案)

  • 每个对象独立开辟空间
  • 资源不共享,安全不冲突。

6.3 现代写法(最优)

cpp 复制代码
String(const String& s) : _str(nullptr) {
    String tmp(s._str);
    swap(_str, tmp._str);
}

String& operator=(String s) {
    swap(_str, s._str);
    return *this;
}

6.4 写时拷贝 COW

  • 浅拷贝 + 引用计数。
  • 读共享,写才真正开空间。
  • 拖延症式高效优化。

7 string 模拟实现(面试可直接手写)

cpp 复制代码
class String {
public:
    String(const char* str = "") {
        if (str == nullptr) str = "";
        _str = new char[strlen(str) + 1];
        strcpy(_str, str);
    }

    // 深拷贝现代写法
    String(const String& s) : _str(nullptr) {
        String tmp(s._str);
        swap(_str, tmp._str);
    }

    String& operator=(String s) {
        swap(_str, s._str);
        return *this;
    }

    ~String() {
        delete[] _str;
        _str = nullptr;
    }

    const char* c_str() const { return _str; }
    size_t size() const { return strlen(_str); }
    char& operator[](sslocal://flow/file_open?url=size_t+i&flow_extra=eyJsaW5rX3R5cGUiOiJjb2RlX2ludGVycHJldGVyIn0=) { return _str[i]; }

private:
    char* _str;
};

8 OJ 实战:string 高频题(带答案)

8.1 仅仅反转字母

cpp 复制代码
string reverseOnlyLetters(string s) {
    int l = 0, r = s.size()-1;
    while (l < r) {
        if (!isalpha(s[l])) l++;
        else if (!isalpha(s[r])) r--;
        else swap(s[l++], s[r--]);
    }
    return s;
}

8.2 第一个只出现一次的字符

cpp 复制代码
int firstUniqChar(string s) {
    int cnt[256] = {0};
    for (auto ch : s) cnt[ch]++;
    for (int i = 0; i < s.size(); ++i)
        if (cnt[s[i]] == 1) return i;
    return -1;
}

8.3 字符串相加(大数加法)

cpp 复制代码
string addStrings(string num1, string num2) {
    int i = num1.size()-1, j = num2.size()-1;
    string res;
    int carry = 0;
    while (i >= 0 || j >= 0 || carry) {
        int sum = carry;
        if (i >= 0) sum += num1[i--] - '0';
        if (j >= 0) sum += num2[j--] - '0';
        carry = sum / 10;
        res += (sum % 10) + '0';
    }
    reverse(res.begin(), res.end());
    return res;
}

9 string 核心要点总结(背会直接面试)

  1. string 是管理字符数组的类,彻底替代 C 风格字符串。
  2. 优先用:+=size()reservec_str()
  3. 遍历三法:[]、迭代器、范围 for。
  4. resize 改长度,reserve 改容量
  5. 底层:VS 用 SSO,GCC 用 COW。
  6. 面试核心:浅拷贝/深拷贝、模拟实现、扩容机制
  7. OJ 高频:反转、去重、字符串加法、回文判断。

10 结尾 & 引流

本文由 C++ 后端学习笔记整理,后续将持续更新:

  • vector 底层原理与模拟实现
  • list、map、unordered_map 深度剖析
  • STL 面试 100 题
  • 计算机基础、操作系统、网络

觉得有用请 点赞 + 收藏 + 关注,第一时间收到硬核干货更新!


相关推荐
南境十里·墨染春水2 小时前
C++笔记 Lambda表达式
开发语言·c++·笔记
悟渔2 小时前
用于STM32的C++编程的LED对象
c++·stm32·单片机
程序员榴莲2 小时前
Java(十二)抽象类
java·开发语言
超级大只老咪2 小时前
线性递推通用模板
java·开发语言·算法
17(无规则自律)2 小时前
DFS:带重复项的全排列,程序运行全流程解析
c++·算法·深度优先
coNh OOSI2 小时前
Spring Boot问题总结
java·spring boot·后端
ISkp3V8b42 小时前
基于项目工程构建SBOM(软件物料清单)的研究
java·visual studio
郝学胜-神的一滴2 小时前
「栈与缩点的艺术」二叉树前序序列化合法性判定:从脑筋急转弯到工程实现
java·开发语言·数据结构·c++·python·算法
她说..2 小时前
Java Object类与String相关高频面试题
java·开发语言·jvm·spring boot·java-ee