C++数组、字符串、string 基础

一、数组(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)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值