一、数组(Array)—— 固定长度的连续内存容器
数组是相同类型元素的连续集合,长度在定义时固定,无法动态扩容,是c++中最基础的容器。
1. 核心定义方式
#include<iostream>
using namespace std;
int main(){
//方式一:直接定义长度和内容
int arr1[5] = {1, 2, 3, 4, 5};//数组长度为5
//方式二:定义部分内容,默认未定义的部分为0
int arr2[5] = {1, 2, 3} ;
//方式三:定义内容,长度自动识别
int arr3[] = {1, 2, 3, 4, 5};
//方式四:动态数组,需要手动释放内存
int* arr4 = new int[5];//长度5,未初始化(值随机)
arr4[0] = 10;//手动赋值
delete[] arr4;// 释放动态数组(必须加[],否则内存泄漏)
return 0;
}
2. 核心操作
- 访问元素时从下标0开始:arr[0];
- 遍历数组时有两种方式一种是用for循环遍历数组下标:for(int i = 0; i < n; i++){ cout<< arr[i];};另一种是for循环遍历数组:for(int x;arr){ cout<< x;}
- 计算长度(静态数组):sizeof(arr)/aizeof(arr[0]),动态数组无效;
- 修改元素直接通过下标来修改:arr[0] = 10;
3. 坑点
- 越界访问会导致程序崩溃或乱码(访问超过数组长度的位置);
- sizeof动态数组得到的是指针的大小不是数组的长度;
- 动态数组分配内存后要释放,否则会造成内存泄漏;
二、字符数组(C 风格字符串)—— 以 '\0' 结尾的字符数组
C 风格字符串是以空字符'\0'(ASCII 码 0)结尾的 char 数组,是 C 语言遗留的字符串形式,C++ 中仍常用,但易出错。
1. 核心定义
#include<iostream>
#include <cstring> // 必须包含:字符串操作函数的头文件
using namespace std;
int main(){
//方式一:直接初始化自动加'\0'
char str1[] = "hello";
//方式二:指定长度加初始化需要手动加 '\0'
char str2[6] = {'h', 'e', 'l', 'l', 'o', '\0'} ;
return 0;
}
2. 核心操作(需要借助<cstring>头文件)
- 获取长度:strlen(str1),只获取有效长度5,不包括'\0';
- 字符串拷贝:strcpy(str2, str1),把str1拷贝到str2,需要str2的长度足够;
- 字符串拼接:strcat(str1, str2),把str2拼接到str1末尾;
- 字符串比较:strcmp(str1, str2),相等返回 0,str1>str2 返回正数,反之负数;
3.坑点
- 字符数组定义时忘记加'\0',strlen会遍历到随机位置,造成程序崩溃;
- 初始化字符数组长度时没有加上'\0',缓冲区溢出会造成越界;
- 不能直接用"="对字符数组进行赋值,字符数组名是常量指针,不能直接赋值(需用
strcpy);
三、string字符串(C++风格字符串)
string是 C++ STL 提供的字符串类,封装了字符数组,支持动态扩容、安全操作。
1. 核心定义(必须包含string头文件)
#include<iostream>
#include<string>
using namespace std;
int main(){
//方式一:初始化空字符串
string s1;
//方式二:初始化字符串并赋值;
string s2 = "hello";
string s3("hello");
//方式三:重复字符初始化
string s4(5,'a');//s4 = "aaaaa"
//方式四:字符数组赋值字符串
char str1[] = "hello";
string s5(str1);
cout<<s1<<endl<<s2<<endl<<s3<<endl<<s4<<endl<<s5;
return 0;
}
2. 核心操作
| 操作 | 代码示例 | 说明 |
| 获取长度 | s2.length()/s2.size() | 等价,返回有效字符数 |
| 访问字符 | s2[0]/s2.at(0) | []不越界检查,at()越界抛异常 |
| 字符串拼接 |
s2+="world"/s2.append("world") | 加到s2末尾,自动扩容安全 |
| 字符串比较 | s2==s3/s2>s3 | 按照ASCLL码比较,直接用运算符 |
| 字符串赋值 | s2=s3 | 直接赋值 |
| 清空字符串 | s2.clear() | 清空后s2.empty()返回true |
| 截取字符 | s2.substr(1,3) | 从下标1的字符开始截取三个字符 |
| 查找字符或者字串 | s2.find('l') | 返回找到的第一个字符下标,找不到返回string::npos |
3. 坑点
- sizeof(s2),返回的不是字符串的长度而是string 类对象的大小8字节;
- find函数找不到时返回string::npos(值为-1,类型是szie_t无符号),判断时必须用pos != string::npos;
4. 常用方法示例
#include<iostream>
#include<string>
using namespace std;
int main(){
string s = "hello world";
//遍历字符串
for(int i = 0; i < s.size(); i++){
cout<<s[i];
}
cout<<endl;
for(char x: s){
cout<<x;
}
cout<<endl;
//字符串比较
string s1 = "hello c++";
if(s == s1){
cout<<"字符串相同"<<endl;
}else{
cout<< "s > s1 的结果:" << (s > s1) <<endl;
}
//字符串拼接
s.append("i love you");
s1+="i love you";
cout<< "拼接后s:" <<s<<endl<< "拼接后s1:" <<s1<<endl;
//查找与替换
size_t pos = s1.find("c++");
if(pos != string::npos){
s1.replace(pos,3,"java");//替换从pos开始的三个字符为java
}
cout << "替换后s1:" << s1 <<endl;
const char* str = s.c_str();//返回const char*类型,不能修改
cout << "C风格字符串s:"<< str << endl;
return 0;
}
四、总结
1. 数组固定内存,无越界检查易溢出,用静态数组用sizeof()获取长度,动态数组需要释放内存,用堆/栈存储;
2. 字符数组固定内存,初始化时需要加上'\0',用cstring头文件并且无越界检查,用堆/栈存储;
3.string字符串,at()函数有溢出检查,依靠string头文件,动态管理自动释放;
五、综合运用
1. 反转字符串
解法1:
#include<iostream>
#include<string>
using namespace std;
//避免拷贝造成开销,const仅读取不修改
string reverse(const string& s){
int len = s.size();
string s1;
for(int i = len-1; i >= 0; i--){
s1 += s[i];
}
return s1;
}
int main(){
string s;
cout << "输入字符串";
cin.ignore();
getline(cin,s);
cout << "反转后的字符串" << reverse(s);
return 0;
}
解法2:
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
void stringReverse(string& s){
int left = 0;
int right = s.size()-1;
while(left < right){
swap(s[left], s[right]);//swap函数用来交换左右指针字符
left++;
right--;
}
}
int main(){
string s;
cout << "输入字符串:";
cin.ignore();
getline(cin,s);
stringReverse(s);
cout << "反转后的字符串:" << s <<endl;
return 0;
}
2. 判断字符串是否由数字组成
#include<iostream>
#include<string>
using namespace std;
bool isAllDigit(const string& s){
for (char c : s) {
// 判断字符是否在0-9范围内
if (c < '0' || c > '9') {
return false;
}
}
return true;
}
int main(){
string s;
cout<< "请输入字符串: ";
cin.ignore();
getline(cin, s);
// 边界处理:空字符串(面试加分项)
if (s.empty()) {
cout << "输入的字符串为空!" << endl;
return 0;
}
if(isAllDigit(s)){
cout << "字符串由数字组成" << endl;
}else{
cout << "字符串不是由数字组成" << endl;
}
return 0;
}
cctype头文件中有判断字符串是否由数字组成的函数isdigit(),返回非0表示是数字,0表示非数字。同时isdigit()类型为int,使用时需要强转static_cast<int>(c)。

2万+

被折叠的 条评论
为什么被折叠?



