【C++字符串】char*、const char*、char[]和std::string

📅 2026/7/23 20:12:21 👁️ 阅读次数 📝 编程学习
【C++字符串】char*、const char*、char[]和std::string
专栏网址:https://blog.csdn.net/zhujushu/category_13112687.html

0.概述

在程序开发中,字符串操作是必不可少的功能之一。在众多编程语言中,C++对字符串有着底层、较良好的支持。

C++ 提供了以下两种字符串表示形式:

  • C语言风格 const char*、char[]、char* 等类型;
  • C++ std::string 类类型。

本文将介绍以上字符串类型使用的方式,并重点讲述std::string的功能。

1.const char*

const char* 是一个不可变的字符串常量类型,看以下代码:

const char* Str = "Hello World!";

里面 Str、"Hello World!" 都是const char*类型的,它可以是左值,也可以是右值。

注意区分const char* 和 char* const

char * const CConst; //指向字符的静态指针 const char * ConstC; //指向静态字符的指针

当const char*的值是一个右值时,C++编译器会在const char*的末尾添加'\0'。

2.char[]

char[]代表字符数组,可以对应一个字符串,如

char b[]="string2"; //b的长度是字符的数量+1 //因为gcc/g++编译器会在const char*的末尾添加'\0'

这里b是一个char数组(字符数组),每个元素对应一个字符,最后的元素为'\0'。

区别如下:

注意:char型数组的名字,也是该数组首元素的地址,是常量,不能改变。但char型数组的每个元素可以改变。

char b[]="Hello World!";//定义 printf("%s\n",b);//输出

结果:
Hello World!

3.char*

char* 是指向字符串的指针,与const char*不同的是,char*的值可以改变。

看以下代码:

char* Str = "Hello World!";//定义 Str="Hi!"; printf("%s\n",Str);

输出:

Hi!

里面 Str是char*类型的。

注意区分char[] 和 char* :

char * C = "Hello!"; C = "Hi!";//合法 C[0] = 'A';//非法访问只读内存非法 char CC[] = "Hello!"; CC = "Hi!";//报错,首元素地址无法改变 CC[0] = 'A';//合法

在ISO C++中,char* 被指明是危险的,它可能导致内存泄漏、溢出等风险,在开发中要慎用。

4.std::string

std::string是 C++ 标准库中提供的字符串类,用于处理动态大小的字符序列。它属于std命名空间,封装了字符串的存储和管理,提供了丰富的成员函数和操作符,简化了字符串操作。

头文件

使用std::string要引入<string.h>头文件,代码如下:

#include <string.h> //using namespace std; //使用引入的标准库的全部内容,使用时无需std::前缀,但容易造成重声明和污染 //using std::string; //同"using namespace std;",但只使用string类类型,推荐

基本用法

声明和初始化std::string可以通过多种方式完成:

std::string str1; // 默认初始化,空字符串 std::string str2("Hello"); // 从 C 风格字符串初始化 std::string str3(str2); // 从另一个 std::string 初始化 std::string str4(5, 'a'); // 重复字符初始化,结果为 "aaaaa"

常用成员函数

std::string提供了大量成员函数,以下是一些常用功能:

访问字符

char c = str2[0]; // 通过下标访问,不检查边界 char c2 = str2.at(1); // 通过 at() 访问,会检查边界

修改字符串

str1.append(" World"); // 追加字符串 str1.push_back('!'); // 追加单个字符 str1.insert(5, " C++"); // 在指定位置插入 str1.erase(5, 4); // 删除子串

容量操作

size_t len = str1.size(); // 获取字符串长度 bool empty = str1.empty(); // 判断是否为空 str1.resize(10); // 调整字符串大小

字符串操作

查找和替换

size_t pos = str1.find("World"); // 查找子串 if (pos != std::string::npos) { str1.replace(pos, 5, "Universe"); // 替换子串 }

子串提取

std::string sub = str1.substr(6, 5); // 提取从位置 6 开始的 5 个字符

输入输出

std::string可以与标准输入输出流配合使用:

std::string input; std::cin >> input; // 读取一个单词 std::getline(std::cin, input); // 读取一行 std::cout << input << std::endl; // 输出字符串

与 C 库函数互通

与 C 库函数交互时,由于使用的是const char* 或 char[],会造成类型不匹配。

std::string 提供了c_str()以获取const char*指针:

const char* cstr = str1.c_str();

性能与注意事项

  • std::string动态管理内存,自动处理存储空间的分配和释放。
  • 频繁的字符串拼接可能导致多次内存重新分配,影响性能。可以使用reserve()预分配空间优化。

现代 C++ 扩展

C++17 引入了std::string_view,提供对字符串的非拥有视图,适合只读场景,避免不必要的拷贝:

std::string_view view(str1.data(), 5); // 创建前 5 个字符的视图

5.总结

C++提供了多种字符串处理方式,包括C风格字符串(const char*char[]char*)和更现代的std::string类。

C风格字符串需要手动管理内存且易出错,而std::string通过自动内存管理简化了操作,并提供丰富的成员函数支持查找、替换、子串提取等常见需求。

std::string与标准输入输出流无缝集成,同时支持通过c_str()与C风格字符串交互。

C++17引入的std::string_view进一步优化了只读场景的性能。

开发中应优先使用std::string以提升安全性和可维护性,仅在必要场景下谨慎使用C风格字符串。


温馨提示:请留下点赞!