​​C++ string类完全指南:从入门到实战​

目录

​​C++ string类完全指南:从入门到实战​​

​​写给初学者的前言​​

​​一、为什么需要string类?​​

​​1. C语言字符串的烦恼​​

​​2. string类就像智能字符串​​

​​二、string类的基本使用​​

​​1. 创建字符串的5种方式​​

​​2. 最常用的10个操作​​

​​3. 新特性:auto和范围for​​

​​三、string类的底层秘密​​

​​1. string类的存储方式​​

​​2. 为什么需要深拷贝?​​

​​四、实战练习​​

​​1. 反转字符串​​

​​2. 验证回文串​​

​​3. 字符串分割​​

​​五、常见问题解答​​

​​1. string和char[]如何选择?​​

​​2. string会内存泄漏吗?​​

​​3. 为什么有时要用c_str()?​​

​​4. 如何提高string性能?​​

​​六、学习路线建议​​


​C++ string类完全指南:从入门到实战​

​写给初学者的前言​

当你刚开始学习C++时,可能会对字符串处理感到困惑——为什么要有string类?它和C语言的字符数组有什么区别?为什么总说string更好用?这篇文章将用最通俗易懂的方式,带你彻底理解C++中的string类。

​一、为什么需要string类?​

​1. C语言字符串的烦恼​

想象你要记录一个班级的学生姓名:

char name1[20] = "张三";
char name2[20] = "李四";
// 想要拼接两个名字
strcat(name1, name2); // 危险!可能超出20个字符

C语言的字符串就像固定大小的盒子:

  • 必须预先知道最大长度
  • 拼接、复制容易出错
  • 需要记住各种str开头的函数

​2. string类就像智能字符串​

string name1 = "张三";
string name2 = "李四";
string fullName = name1 + name2; // 自动处理内存

string类就像会​​自动扩容的智能容器​​:

  • 不用预先设定大小
  • 基本操作直接用运算符(+, =等)
  • 内存自动管理

​二、string类的基本使用​

​1. 创建字符串的5种方式​

string s1;              // 空字符串
string s2 = "hello";    // 直接赋值
string s3("world");     // 构造函数
string s4(5, 'A');      // "AAAAA"
string s5(s2);          // 拷贝构造

​2. 最常用的10个操作​

// 1. 获取长度
int len = s.size(); // 或者s.length()

// 2. 判断是否为空
if (s.empty()) cout << "字符串为空";

// 3. 访问字符
char c1 = s[0];    // 不检查越界
char c2 = s.at(0); // 会检查越界

// 4. 字符串比较
if (s1 == s2) {...}
if (s1 < s2) {...}  // 按字典序比较

// 5. 字符串连接
s1 += s2;          // 追加
s1.append("!!");   // 同样功能

// 6. 查找子串
int pos = s.find("lo"); // 返回位置或string::npos

// 7. 截取子串
string sub = s.substr(2, 3); // 从位置2开始,取3个字符

// 8. 插入删除
s.insert(3, "插入的内容");
s.erase(3, 5); // 从位置3删除5个字符

// 9. 替换
s.replace(2, 4, "新内容"); // 从位置2开始替换4个字符

// 10. 转换C风格字符串
const char* p = s.c_str();

​3. 新特性:auto和范围for​

// 自动类型推导
auto s = "自动推导为string"s; // 注意结尾的s

// 遍历字符串的每个字符
for (auto ch : s) {
    cout << ch << " ";
}

​三、string类的底层秘密​

​1. string类的存储方式​

string类实际上是在​​堆上动态分配内存​​存储字符,但有两种优化策略:

​VS编译器​​:

  • 短字符串(<16字符)直接存在对象内部
  • 长字符串才在堆上分配
  • 总大小固定为28字节

​GCC编译器​​:

  • 全部在堆上分配
  • 使用​​引用计数​​实现写时复制(COW)
  • 多个string可共享同一内存

​2. 为什么需要深拷贝?​

// 浅拷贝的问题
string s1 = "hello";
string s2 = s1; // 如果只是简单复制指针...
// s1和s2指向同一内存,析构时会重复释放!

string类必须实现​​深拷贝​​:

  • 每个string对象有自己的内存副本
  • 拷贝时会完全复制内容
  • 避免多个对象共享同一内存

​四、实战练习​(oj在线均有原题)

​1. 反转字符串​

void reverseString(string& s) {
    int left = 0, right = s.size() - 1;
    while (left < right) {
        swap(s[left], s[right]);
        left++;
        right--;
    }
}

​2. 验证回文串​

bool isPalindrome(string s) {
    int left = 0, right = s.size() - 1;
    while (left < right) {
        if (s[left] != s[right]) return false;
        left++;
        right--;
    }
    return true;
}

​3. 字符串分割​

vector<string> split(const string& s, char delim) {
    vector<string> tokens;
    string token;
    for (char ch : s) {
        if (ch == delim) {
            if (!token.empty()) {
                tokens.push_back(token);
                token.clear();
            }
        } else {
            token += ch;
        }
    }
    if (!token.empty()) tokens.push_back(token);
    return tokens;
}

​五、常见问题解答​

​1. string和char[]如何选择?​

  • 需要固定大小或与C函数交互 → char[]
  • 其他情况 → string

​2. string会内存泄漏吗?​

不会!string的析构函数会自动释放内存

​3. 为什么有时要用c_str()?​

当需要传递给C函数时:

FILE* f = fopen(s.c_str(), "r");

​4. 如何提高string性能?​

  • 预先用reserve()分配足够空间
  • 少用+运算符,多用+=
  • 传递const string&避免拷贝

​六、学习路线建议​

  1. ​初级阶段​​:掌握基本API,能完成常见操作
  2. ​中级阶段​​:理解内存管理,避免常见陷阱
  3. ​高级阶段​​:研究底层实现,尝试自己实现string类

记住:string是C++中最常用的工具之一,多练习才能真正掌握!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值