csp信奥赛c++之字符数组与字符串的区别
一、字符数组与字符串的区别(详细讲解)
在C++(尤其信奥赛CSP常用环境)中,"字符数组"和"字符串"通常指两种不同的数据类型或存储方式:
| 特性 | 字符数组 (char[]) |
字符串 (std::string) |
|---|---|---|
| 本质 | 由若干连续字符元素构成的数组,以\0(空字符)作为结束标志(C风格字符串)。 |
C++标准库提供的类,封装了动态字符序列,不需显式处理结束符。 |
| 定义方式 | char s[100]; 或 char s[] = "hello"; |
#include <string> 后 string s; 或 string s = "hello"; |
| 结束标志 | 必须有\0,否则不是合法的C字符串,容易越界。 |
内部维护长度,无\0依赖。 |
| 长度获取 | strlen(s) 遍历直到\0,时间复杂度O(n)。 |
s.length() 或 s.size(),O(1)直接返回。 |
| 赋值 | 不能直接用=赋值(除非初始化),需strcpy或循环。 |
支持=赋值、拷贝。 |
| 比较 | strcmp(s1, s2) 按字典序,返回正负0。 |
支持关系运算符 ==, !=, <, >, <=, >=,更直观。 |
| 拼接 | strcat(dest, src) 易溢出,需确保空间足够。 |
+ 或 += 操作符,自动管理内存。 |
| 输入输出 | cin >> s(遇空白停止)或cin.getline(s, size)。cout << s。 |
cin >> s(遇空白停止)或getline(cin, s)。cout << s。 |
| 内存管理 | 固定大小(静态或局部数组),动态分配需new[]并手动释放。 |
自动扩容,自动释放(RAII)。 |
| 常用函数 | strlen, strcpy, strcat, strcmp, strchr等(需<cstring>)。 |
.append(), .substr(), .find(), .replace()等成员函数。 |
| 安全性 | 容易缓冲区溢出,需小心边界。 | 相对安全,但注意[]下标越界(未检查)。 |
核心要点:
- 字符数组本质是数组,C风格字符串是约定以
\0结尾的字符数组。 std::string是类类型,提供面向对象的字符串操作。- 信奥赛中两种都会用到,但
std::string更常用且安全,除非题目明确要求用字符数组(比如内存极紧张或考察C函数)。
二、选择题(单选题,共8题)
1. 关于字符数组与string类型,下列说法正确的是( )
A. 字符数组必须以'\0'结尾,否则strlen函数会出错(产生未定义行为)。
B. string类型的字符串在内存中一定以'\0'结尾。
C. 使用char s[10] = "hello"时,sizeof(s)等于strlen(s)。
D. string对象可以直接用scanf输入。
2. 以下代码片段中,能正确输出字符串长度的是( )
cpp
char a[20] = "CSP";
string b = "NOIP";
A. cout << strlen(a) << " " << b.length();
B. cout << sizeof(a) << " " << sizeof(b);
C. cout << strlen(a) << " " << strlen(b);
D. cout << a.size() << " " << b.size();
3. 若有定义char s[10] = "abc";,则执行strcat(s, "def");后,下列说法正确的是( )
A. 程序正常运行,s变为"abcdef"。
B. 可能发生数组越界,因为空间不足。
C. 编译错误,因为s不能作为strcat的第一个参数。
D. 运行时输出"abcdef"但会导致内存泄漏。
4. 关于字符串输入,以下写法不会出现问题的是( )
A. char s[5]; cin >> s; 用户输入"hello"
B. string s; getline(cin, s);
C. char s[10]; gets(s);
D. string s; scanf("%s", s);
5. 下列表达式中,能正确判断两个C风格字符串是否相等的是( )
A. if (s1 == s2)
B. if (strcmp(s1, s2) == 0)
C. if (strcpy(s1, s2) == 0)
D. if (s1 = s2)
6. 已知char s[20] = "CSP";,以下操作后,输出结果正确的是( )
cpp
strcpy(s, "NOIP");
cout << s;
A. NOIP
B. CSPNOIP
C. NOIP+随机字符
D. 编译错误
7. 若char a[] = "abc"; char b[] = "abc";,则strcmp(a, b)的返回值是( )
A. 0
B. 正数
C. 负数
D. 不确定
8. 以下关于sizeof和strlen的说法,正确的是( )
A. 对char s[10] = "test";,sizeof(s)为5,strlen(s)为4。
B. 对char s[20] = "abc";,sizeof(s)等于strlen(s) + 1。
C. 对string s = "hello";,sizeof(s)等于s.length()。
D. 对char s[] = "hello";,sizeof(s)为6,strlen(s)为5。
三、判断题(正确填√,错误填×,共6题)
1. char str[5] = "China"; 是合法的定义,并且字符串长度为5。 ( )
2. 使用 strlen 计算字符数组长度时,遇到第一个 '\0' 就停止,不会关心数组实际大小。 ( )
3. char s[10]; s = "CSP"; 是正确的赋值语句。 ( )
4. 对于 string s = "abc";,s[3] 的访问是合法的,返回 '\0'。 ( )
5. 使用 cin >> s 输入字符串到 string 对象时,可以读取包含空格的整行文本。 ( )
6. char s[100]; cin.getline(s, 100); 与 string s; getline(cin, s); 都能读取一行,但前者需要指定最大长度。 ( )
四、参考答案及简析
选择题答案
- A (B:string不一定以'\0'结尾;C:sizeof(s)=10,strlen=5;D:scanf不能直接用于string)
- A (B:sizeof(a)=20, sizeof(b)是对象大小;C:strlen(b)错误;D:a没有size()成员)
- A (数组大小10,"abc"占4字节,追加"def"(含'\0')共7字节,空间足够)
- B (A输入"hello"需6字节越界;C gets已废弃危险;D scanf参数错误)
- B (C风格字符串比较用strcmp;==比较地址)
- A (strcpy覆盖原内容)
- A (内容相同,strcmp返回0)
- D (A:sizeof(s)=10,strlen=4;B:sizeof(s)=20,strlen=3,不相等;C:sizeof(s)是类对象固定大小,不是字符串长度)
判断题答案
- × ("China"需6字节(含'\0'),数组只有5,越界)
- √
- × (数组名不能直接赋值)
- × (s[3]越界,未定义行为)
- × (cin >> 遇空白停止,不能读空格)
- √
各种学习资料,助力大家一站式学习和提升!!!
cpp
#include<bits/stdc++.h>
using namespace std;
int main(){
cout<<"########## 一站式掌握信奥赛知识! ##########";
cout<<"############# 冲刺信奥赛拿奖! #############";
cout<<"###### 课程购买后永久学习,不受限制! ######";
return 0;
}
【秘籍汇总】(完整csp信奥赛C++学习资料):
1、csp/信奥赛C++,完整信奥赛系列课程(永久学习):
https://edu.csdn.net/lecturer/7901 点击跳转

2、CSP信奥赛C++竞赛拿奖视频课:
https://edu.csdn.net/course/detail/40437 点击跳转

3、csp信奥赛高频考点知识详解及案例实践:
CSP信奥赛C++动态规划:
https://blog.csdn.net/weixin_66461496/category_13096895.html点击跳转
CSP信奥赛C++标准模板库STL:
https://blog.csdn.net/weixin_66461496/category_13108077.html 点击跳转
信奥赛C++提高组csp-s知识详解及案例实践:
https://blog.csdn.net/weixin_66461496/category_13113932.html 点击跳转
4、csp信奥赛冲刺一等奖有效刷题题解:
CSP信奥赛C++初赛及复赛高频考点真题解析(持续更新): https://blog.csdn.net/weixin_66461496/category_12808781.html 点击跳转
信奥赛C++提高组csp-s初赛&复赛真题题解(持续更新):
https://blog.csdn.net/weixin_66461496/category_13125089.html 点击跳转
5、GESP C++考级真题题解:

GESP(C++ 一级+二级+三级)真题题解(持续更新):https://blog.csdn.net/weixin_66461496/category_12858102.html 点击跳转

GESP(C++ 四级+五级+六级)真题题解(持续更新):https://blog.csdn.net/weixin_66461496/category_12869848.html 点击跳转

GESP(C++ 七级+八级)真题题解(持续更新):
https://blog.csdn.net/weixin_66461496/category_13117178.html 点击跳转
· 文末祝福 ·
cpp
#include<bits/stdc++.h>
using namespace std;
int main(){
cout<<"跟着王老师一起学习信奥赛C++";
cout<<" 成就更好的自己! ";
cout<<" csp信奥赛一等奖属于你! ";
return 0;
}
