火龙信奥
  • 分享
  • 课程
  • 在线题库
  • CSES
    • GESP
    • CSP
  • 打卡
    • 代码对战
    • 快速对战
  • 题单
  • 知识课堂
  • 在线比赛
  • 团队
  • 荣誉墙
  • 商城
  • 登录 / 注册

三级 - 字符数组与字符串函数

作者: 作者的头像   huolong , 时间:2026-10-05 16:17:28 , 所有人可见, 阅读  19

GESP C++ 三级算法与基础专项讲义:字符数组与字符串函数

在 C++ 中,字符串主要有两种处理方式:一是从 C 语言继承过来的C 风格字符串(以 \0 结尾的字符数组),二是 C++ 标准库中的 string 类。GESP 三级考试中,对 C 风格字符串及其底层函数的考查非常频繁。


第一部分:C 风格字符串与核心库函数详解

C 风格字符串本质上是一个以空字符 '\0'(ASCII 码为 0)作为结束标志的字符数组。要使用 C 风格字符串的库函数,必须在程序头部包含头文件 #include <cstring>(或 <string.h>)。

1. strlen() —— 计算字符串长度

  • 功能:计算字符串的实际长度,不包括结束符 '\0'。
  • 返回值:size_t(通常为无符号整数)。
  • 代码举例: ```cpp #include #include using namespace std;

int main() { char str1[] = "Hello"; // 虽然只写了5个字符,但编译器会自动在末尾补 '\0',实际占用空间为6 char str2[10] = "GESP"; // 占用10个字节,但有效字符只有4个

  cout << strlen(str1) << endl; // 输出: 5
  cout << strlen(str2) << endl; // 输出: 4
  cout << sizeof(str1) << endl; // 输出: 6 (sizeof计算的是数组总内存大小)
  return 0;

} ```

2. strcpy() —— 字符串复制

  • 功能:将源字符串(包括 '\0')复制到目标字符数组空间中。
  • 注意:目标数组必须足够大,否则会发生内存溢出(Buffer Overflow)。
  • 代码举例: ```cpp #include #include using namespace std;

int main() { char src[] = "C++ Level 3"; char dest[20]; // 确保目标空间足够大

  strcpy(dest, src); // 将 src 复制到 dest
  cout << "dest = " << dest << endl; // 输出: dest = C++ Level 3
  return 0;

} ```

3. strcat() —— 字符串连接

  • 功能:将源字符串连接到目标字符串的后面,会覆盖目标字符串末尾的 '\0',并在连接后的新字符串末尾自动补上 '\0'。
  • 注意:目标数组必须有足够的剩余空间容纳源字符串。
  • 代码举例: ```cpp #include #include using namespace std;

int main() { char dest[30] = "Hello "; char src[] = "World!";

  strcat(dest, src); // 把 src 接在 dest 后面
  cout << dest << endl; // 输出: Hello World!
  return 0;

} ```

4. strcmp() —— 字符串比较

  • 功能:按照 ASCII 码值的大小顺序,从左到右逐个字符进行比较,直到出现不同的字符或遇到 '\0' 为止。
  • 返回值:
  • 若 str1 小于 str2,返回负数(通常为 -1)
  • 若 str1 等于 str2,返回 0
  • 若 str1 大于 str2,返回正数(通常为 1)
  • 代码举例: ```cpp #include #include using namespace std;

int main() { char s1[] = "apple"; char s2[] = "banana"; char s3[] = "apple";

  cout << strcmp(s1, s2) << endl; // 输出: 负数(因为 'a' 的ASCII码小于 'b')
  cout << strcmp(s2, s1) << endl; // 输出: 正数
  cout << strcmp(s1, s3) << endl; // 输出: 0(两字符串完全相同)
  return 0;

} ```


第二部分:C++ string 类及其常用操作

在现代 C++ 编程中,推荐使用标准库中的 string 类。它由 #include <string> 提供,使用时更为安全、灵活,能够自动管理内存,避免了字符数组越界和漏写 '\0' 的烦恼。

1. 声明与初始化

string s1;              // 默认空字符串
string s2 = "Hello";    // 直接初始化
string s3(5, 'A');      // 初始化为由5个'A'组成的字符串 "AAAAA"

2. 核心成员函数与操作符

  • 赋值与拼接:可以直接使用 = 进行赋值,使用 + 进行字符串拼接。 cpp string a = "Hello"; string b = " GESP"; string c = a + b; // c 的内容为 "Hello GESP"
  • 获取长度:使用 .length() 或 .size()。 cpp string s = "China"; cout << s.length(); // 输出: 5
  • 子串提取 .substr(pos, len):从下标 pos 开始,截取长度为 len 的子串。 cpp string s = "Programming"; cout << s.substr(3, 4); // 从下标3开始,截取4个字符,输出: gram
  • 查找 .find(str):查找子串或字符第一次出现的位置,若找不到返回 string::npos。 cpp string s = "hello world"; cout << s.find("world"); // 输出: 6

第三部分:C 风格字符数组 vs C++ string 类辨析

这是 GESP 三级考试中极易出概念选择题的高频考点,务必掌握:

比较维度 C 风格字符串(字符数组 char[]) C++ string 类对象
本质 内存中连续存储的一段字符,必须以 '\0' 结尾。 标准库模板类,封装了动态内存管理的细节。
赋值方式 声明后不能直接用 = 整体赋值,必须用 strcpy()。 支持直接用 = 进行整体赋值。
长度获取 必须使用 <cstring> 中的 strlen() 函数。 可以直接调用成员函数 .length() 或 .size()。
连接方式 需要使用 strcat() 函数。 直接使用算术运算符 + 或 += 即可。
比较方式 不能直接用 ==(== 比较的是数组在内存中的地址),必须用 strcmp()。 支持直接使用 ==, <, > 等运算符比较字典序。
安全性 较低。如果操作不慎容易导致数组越界或 '\0' 丢失。 较高。会自动扩容,不易发生缓冲区溢出。

第四部分:GESP 风格课后练习题

一、 单选题

1. 以下关于 C++ 中 string 类与字符数组(char[])的说法,错误的是( ) A. string 对象可以直接使用 = 进行赋值,而字符数组需要使用 strcpy。
B. string 对象的长度可以使用 length() 成员函数获取,而字符数组需要使用 strlen() 函数。
C. string 对象和字符数组都可以直接使用 == 运算符来比较两个字符串的内容是否完全相同。
D. 字符数组必须以 '\0' 作为字符串结束的标记,而 string 对象不需要程序员手动管理结束标志。

2. 执行以下 C++ 代码,其输出结果是( )

#include <iostream>
#include <cstring>
using namespace std;
int main() {
    char str[20] = "GESP";
    strcat(str, "3");
    cout << strlen(str) << endl;
    return 0;
}

A. 4
B. 5
C. 6
D. 20

3. 若有定义 char s1[] = "bca"; char s2[] = "abc";,则执行 int res = strcmp(s1, s2); 后,变量 res 的值是( ) A. 大于 0 的正数
B. 等于 0
C. 小于 0 的负数
D. 编译错误

4. 以下代码片段执行后的输出结果是( )

#include <iostream>
#include <string>
using namespace std;
int main() {
    string s = "2026_GESP";
    cout << s.substr(5, 4) << endl;
    return 0;
}

A. 2026
B. GESP
C. 026_
D. 26_G


二、 编程实践题

5. 统计字符个数 * 题目描述:编写一个 C++ 程序,输入一行包含空格的字符串(可以使用 cin.getline),再输入一个要查找的字符。请统计并输出该字符在字符串中出现的次数。 * 输入样例: text hello world l * 输出样例: text 3 * 参考代码模板: ```cpp #include #include using namespace std;

int main() { char str[100]; cin.getline(str, 100); // 读取一行字符串,包含空格 char target; cin >> target;

  int count = 0;
  int len = strlen(str); // 获取字符串长度
  for (int i = 0; i < len; i++) {
      if (str[i] == target) {
          count++;
      }
  }
  cout << count << endl;
  return 0;

} ```


练习题参考答案与解析

  1. 答案:C
  2. 解析:在 C++ 中,string 对象可以直接使用 == 比较内容。但是对于原生的 char[] 字符数组,直接使用 == 比较的是它们在内存中的首地址,无法正确比较内容是否相同,因此 C 选项说法错误。

  3. 答案:B

  4. 解析:初始时 str 内存储 "GESP"(长度为4)。执行 strcat(str, "3") 后,str 变为 "GESP3"。此时再用 strlen(str) 计算长度,结果为 5。

  5. 答案:A

  6. 解析:strcmp 是逐个字符对比 ASCII 码。比较 s1("bca")和 s2("abc")时,先比较第一位:'b' 的 ASCII 码大于 'a',因此 s1 > s2,strcmp 返回一个正数。

  7. 答案:B

  8. 解析:s.substr(5, 4) 表示从下标 5 开始(字符 'G'),连续截取 4 个字符,即 "GESP"。

—— 本文来自火龙信奥(义乌睿码科技):义乌青少年信息学奥赛与编程教育平台,专注 CSP-J/S、NOIP、GESP 竞赛培训,线上线下融合教学,助力编程升学。网址:hlcoding.com

关于火龙

  • 关于我们
  • 学员获奖
  • 预约试听
  • ACM课程
  • CSP课程
  • 学习指南

帮助中心

  • 用户协议
  • 打字练习 HOT
  • 在线画图
  • DevC++下载
  • CSP报名
  • GESP官网

推荐课程

  • C++零基础入门(可试看)
  • C++进阶提升
  • GESP考级辅导
  • GESP打卡
  • CSP-J/S打卡

公众号

火龙信奥公众号二维码

© 2017-2026 义乌市睿码科技有限公司版权所有 浙ICP备2021013995号

火龙信奥
请输入登录信息


请完成安全验证
验证码底图 滑块
向右拖动滑块完成验证
请输入用户名 / 绑定的手机号码



请输入注册信息(手机号验证码注册)





验证码5分钟有效,60秒内不可重复获取,每日最多3次

微信登录

微信登录二维码

正在生成二维码...

账号已过期,请续期。
去续期

绑定手机号

📱

为了更好地保护您的账号安全,享受完整的平台服务

请您尽快绑定手机号码