C/C++字符串

1.C 语言中的字符串

C 语言没有专门的 "字符串类型",字符串的本质:字符串是通过字符数组(char[] 间接表示的,其本质是以空字符 '\0' 结尾的字符序列(称为 "C 风格字符串")。

定义方式:

cs 复制代码
// 字符数组初始化(自动添加 '\0' 结尾)
char str1[] = "hello";  // 等价于 {'h','e','l','l','o','\0'}
char str2[6] = {'h','e','l','l','o','\0'};  // 必须显式添加 '\0'

关键特性:

依赖空字符 '\0' 标识结束(否则字符串函数无法判断长度);

本质是 char 类型的数组,需手动管理内存(长度固定,或通过指针动态分配);

操作依赖 <string.h> 库函数(如 strlen 求长度、strcpy 复制、strcat 拼接等)。

2. C++ 中的字符串

C++ 兼容 C 风格的字符数组,同时提供了标准库中的 std::string 类型(属于类类型),专门用于处理字符串,更安全、便捷。

定义方式:

cpp 复制代码
#include <string>  // 必须包含头文件
using namespace std;  // 或显式使用 std::string

std::string str = "hello";  // 直接初始化,无需手动添加 '\0'

关键特性:

属于 std 命名空间下的类(std::string),封装了字符串的存储和操作。

自动管理内存(长度可动态变化,无需手动分配 / 释放);

支持直接用 + 拼接、[] 访问字符、length() 获取长度等直观操作;

可与 C 风格字符串相互转换(通过 c_str() 方法获取 C 风格字符串指针)。

3.string和字符数组的区别

在 C 语言中,需要先明确一个重要前提:C 语言没有原生的 string 类型 (这一点和 C++ 的 std::string 不同)。我们通常说的 "C 语言字符串"(简称 "C 字符串"),本质是一种特殊的字符数组 ------ 它必须以空字符 '\0' 作为结尾,用于标识字符串的结束。

普通字符数组 :是 char 类型元素的集合,仅存储字符序列,不要求必须包含 '\0'。其长度由初始化时的元素个数或定义时指定的大小决定。

cs 复制代码
// 普通字符数组(无 '\0' 结尾)
char arr1[] = {'h', 'i'};  // 长度为 2(仅包含 'h'、'i')
char arr2[5] = {'a', 'b'}; // 长度为 5(前 2 个是 'a'、'b',后 3 个默认填充 '\0',但这是编译器行为,非必须)

C 字符串 :是'\0' 结尾的字符数组'\0' 是字符串的 "结束标志"(不属于有效字符)。其 "字符串长度"(有效字符数)是 '\0' 之前的字符个数,数组实际长度需至少比字符串长度多 1(容纳 '\0')。

cs 复制代码
// C 字符串(自动添加 '\0' 结尾)
char str1[] = "hello";  // 等价于 {'h','e','l','l','o','\0'},数组长度 6,字符串长度 5
char str2[6] = {'h','i','\0'};  // 显式添加 '\0',数组长度 6,字符串长度 2

C 语言的字符串函数(如 <string.h> 中的 strlenstrcpystrcatprintf("%s") 等)仅能正确处理 "以 '\0' 结尾的字符数组" (即 C 字符串),因为它们依赖 '\0' 来判断字符串的结束位置。

C 字符串 使用字符串函数:行为正确。

cs 复制代码
char str[] = "test";
printf("%s", str);  // 正确输出 "test"(找到 '\0' 后停止)
int len = strlen(str);  // 正确返回 4(仅统计 '\0' 前的字符)

普通字符数组(无 '\0' 结尾) 使用字符串函数:行为未定义(可能越界访问)。

cs 复制代码
char arr[] = {'a', 'b'};  // 无 '\0' 结尾
printf("%s", arr);  // 错误:会一直打印直到内存中随机遇到 '\0',可能输出乱码
int len = strlen(arr);  // 错误:结果随机(越界查找 '\0')

本质关系:

C 字符串是一种特殊的字符数组 :它在普通字符数组的基础上,强制要求以 '\0' 结尾,从而能被字符串函数识别和处理。

普通字符数组若手动添加 '\0' 结尾,就会变成 C 字符串。例如:

cs 复制代码
char arr[] = {'a', 'b', '\0'};  // 此时 arr 就是一个 C 字符串(长度 2)

在 C 语言中,不能说字符串的数据类型是 char* ,但 char*(字符指针)是最常用的操作字符串的工具char* 是 "字符指针类型",它本身不是字符串类型,但它可以指向字符串(字符数组)的首地址,从而通过指针操作字符串。

cs 复制代码
// 字符串(字符数组)
char str[] = "hello";  // 类型是 char[6](数组类型)

// char* 指针指向字符串的首地址
char* p = str;  // p 指向 str[0]('h'),通过 p 可以访问整个字符串

此时,p 的类型是 char*,但它指向的是字符串(str 这个字符数组)。我们操作字符串时(如用 printf("%s", p) 打印、用 strlen(p) 计算长度),本质是通过 char* 指针找到字符串的起始位置,再按 "'\0' 结尾" 的规则遍历。

相关推荐
zzzyyy5382 小时前
C++之vector容器
开发语言·c++
uotqwkn89469s3 小时前
如果Visual Studio不支持C++14,应该如何解决?
c++·ide·visual studio
Maple_land4 小时前
Linux复习:冯·诺依曼体系下的计算机本质:存储分级与IO效率的底层逻辑
linux·运维·服务器·c++·centos
ue星空4 小时前
UE核心架构概念
网络·c++·ue5
ShineWinsu6 小时前
对于数据结构:堆的超详细保姆级解析——下(堆排序以及TOP-K问题)
c语言·数据结构·c++·算法·面试·二叉树·
_OP_CHEN7 小时前
C++进阶:(五)map系列容器的全面解析
开发语言·c++·map·红黑树·stl容器·键值对·mapoj题
hetao17338377 小时前
ZYZ28-NOIP模拟赛-Round4 hetao1733837的record
c++·算法
大米粥哥哥7 小时前
c++ libcurl报错Send failed since rewinding of the data stream failed【已解决】
开发语言·c++·http·curl·rewind
Nebula_g7 小时前
C语言应用实例:解方程(二分查找)
c语言·开发语言·学习·算法·二分查找·基础
woshimyc7 小时前
ESP32连接ThingsCloud上传设备数据(智慧小灯)
c++·物联网