当前位置: 首页 > article >正文

C++字符串相关内容

字符串

字符串,本质上是一个接一个字符的一组字符。字母、数字、符号等。

const char*  字符串名

字符后面会有一个空终止符,为0。

字符串从指针的内存地址开始,然后继续下去,直到它碰到0,然后意识到字符串终止了。

#include <iostream>
int main()
{
	const char* name = "Miles";  //使用const之后,就不能再改变该字符串的内容。
	//name[2] = "a";
	char name2[5] = {'M','i','l','e','s'};
	std::cout << name << std::endl;
	std::cout << name2 << std::endl;
	std::cin.get();
}

为了使得代码更加简洁,通常会引入string。

string中有一个构造函数,它接收char*或const char*参数。

#include <iostream>
#include <string>
int main()
{
	std::string name1 = "Miles";
	std::cout << name1 << std::endl;
	std::cin.get();
}

std::string 是一个有很多功能的类。

name.size()可以找到其尺寸;strlen(),字符串的长度;strcpy,复制字符串;

字符串相加,可以考虑重载运算符:“+=”。

#include <iostream>
#include <string>
int main()
{
	std::string name1 = "Miles";
	name1 += " hello!";
	std::cout << name1 << std::endl;
	std::cin.get();
}
//输出:
//Miles hello!

字符串相加,或者可以用另一种方法进行:将两个相加的字符数组的其中一个,显式调用一个string构造函数。相当于创建了一个字符串,然后附加这个字符串给另一个。

#include <iostream>
#include <string>
int main()
{
	std::string name1 = std::string("Miles")+ " hello!";
	std::cout << name1 << std::endl;
	std::cin.get();
}
//输出:
//Miles hello!

如果要寻找字符串中的文本,可以使用name.find()。

#include <iostream>
#include <string>
int main()
{
	std::string name1 = std::string("Miles")+ " hello!";
	bool contains = name1.find("es") != std::string::npos;  
	std::cout << name1 << std::endl;
	std::cin.get();
}

其中,std::string::npos代表一个不存在的位置。将结果给contains。

#include <iostream>
#include <string>
void PrintString(std::string string)
{
	string += "h";
	std::cout << string << std::endl;
}
int main()
{
	std::string name1 = std::string("Miles")+ " hello!";
	PrintString(name1);
	bool contains = name1.find("es") != std::string::npos;  
	std::cout << name1 << std::endl;
	std::cin.get();
}
//输出:
//Miles hello!h
//Miles hello!

需要分配一个全新的char数组,来存储我们已经得到的完全相同的文本。

字符串复制,实际上相当慢。

当我们需要传递一个字符串,而且在只读的情况下,需要确保通过常量引用传递它。此时通常在前面加上const和引用&。

void PrintString(const std::string& string)
{
	//string += "h";
	std::cout << string << std::endl;
}

字符串字面量

字符串字面量,是在双引号之间的一串字符。

字符串后面有一个额外的字符,叫做:空终止字符。

#include <iostream>
#include <string>

#include <stdlib.h>
int main()
{
	const char name[7] = "Mi\0les";
	std::cout << strlen(name) << std::endl; //打印出字符串的长度。
	std::cin.get();
}

字符串的相加,还能用到string_literals库。在字符串后面加上s,即可实现字符串的相加。

#include <iostream>
#include <string>
#include <stdlib.h>
int main()
{
	using namespace std::string_literals;
	std::string name = "Miles"s + " hello!";
	std::cout << name << std::endl; 
	std::cin.get();
}
//输出:
//Miles hello!

其中,s实际上是一个函数。操作符函数,它返回标准字符串(对象)。

R可以用来忽略转义字符。使得代码更加简洁。

#include <iostream>
#include <string>

#include <stdlib.h>
int main()
{
	const char* example = R"(Line1
line2
line3)"  ;//R忽略转义字符
	const char* ex = "Line1\n"
		"line2\n"
		"line3\n";
	std::cout << example << std::endl;
	std::cout << ex << std::endl;
	std::cin.get();
}

字符串字面量永远保存在内存的只读区域,

关键字const

关键字

const,称为伪关键字。因为它在改变生成代码方面做不了什么。有点像类和结构体的可见性。

#include<iostream>
#include<string>
int main()
{
	const int MAX_AGE = 90;
	std::cin.get();
}

在堆上建立一个整数,就能得到一个指针。此时有两个方案:

  • 逆向引用dereference
  • 重新分配实际的指针,这样会指向别的东西

用const强制定义一个变量为只读常量。但可以强制改变这个定义,如下,利用(int*)可以将const只读常量的值,逆向引用传给另一个变量。

#include<iostream>
#include<string>
int main()
{
	const int MAX_AGE = 90;
	int* a = new int;
	*a = 2;
	a = (int*)&MAX_AGE;
	std::cout << *a << std::endl;
	std::cin.get();
}
//输出:
//90

但,const int* 意味着,不能修改指针指向的内容。该用法和int const*一致。

const int* a = new int;
int const* a = new int;

int* const可以改变指针指向的内容,但不能把实际的指针本身重新赋值,指向别的东西

#include<iostream>
#include<string>
class Entity
{
private:
	int m_X, m_Y;
public:
	int GetX() const //此用法,只能读,不能写。该方法只能进行读操作,不能进行其他的修改操作。
	{
		return m_X;
	}
	void SetX(int x)
	{
		m_X = x;
	}
};
int main()
{
	const int MAX_AGE = 90;
	int* a = new int;
	*a = 2;
	a = (int*)&MAX_AGE;
	std::cout << *a << std::endl;
	std::cin.get();
}

如果用再次复制Entity类的方式,需要分配空间,那样会很慢。可以通过常量引用传递的方式。也就是:const Entity& e

#include<iostream>
#include<string>
class Entity
{
private:
	int m_X, m_Y;
public:
	int GetX() const
	{
		return m_X;
	}
	void SetX(int x)
	{
		m_X = x;
	}
};
void PrintEntity(const Entity& e)
{
	std::cout << e.GetX() << std::endl; //由于GetX()用到了const,才能在这里用到e.GetX()
}
int main()
{
	const int MAX_AGE = 90;
	int* a = new int;
	*a = 2;
	a = (int*)&MAX_AGE;
	std::cout << *a << std::endl;
	std::cin.get();
}

如果要对int GetX() const中的变量进行修改的话,可以引入mutable:

#include<iostream>
#include<string>
class Entity
{
private:
	int m_X, m_Y;
	mutable int var;
public:
	int GetX() const
	{
		var = 2;
		return m_X;
	}
	void SetX(int x)
	{
		m_X = x;
	}
};

mutable允许函数是常量的方法,可以修改变量。

关键字mutable

mutable的两种不同用途:

  • 与const一同使用。
  • 用在lambda表达式中。

或者mutable可以同时覆盖两种情况。

#include <iostream>
#include <string>
class Entity
{
private:
	std::string m_Name;
	mutable int m_DebugCount;
public:
	const std::string& GetName() const
	{
		m_DebugCount++;  //每次调用get的时候,都会记一次数
		return m_Name;
	}
};
int main()
{
	const Entity e;
	e.GetName();

	std::cin.get();
}

在类成员中使用mutable。

lambda基本上像一个一次性的小函数,可以写出来并赋值给一个变量。

#include <iostream>
#include <string>

class Entity
{
private:
	std::string m_Name;
	mutable int m_DebugCount;
public:
	const std::string& GetName() const
	{
		m_DebugCount++;  
		return m_Name;
	}
};
int main()
{
	const Entity e;
	e.GetName();
//lambda的使用如下:
	int x = 8;
	auto f = [&]()
	{
		x++;
		std::cout << x << std::endl;
	};
	f();
	std::cin.get();
}

lambda还有其他的用法,三种auto用法一致。

int x = 8;
auto f = [&]()
{
	x++;
	std::cout << x << std::endl;
};
auto f = [=]() mutable
{
	x++;
	std::cout << x << std::endl;
};
auto f = [=]()
{
	int y = x;
	y++;
	std::cout << x << std::endl;
};
f();


http://www.kler.cn/a/539902.html

相关文章:

  • 【Javascript Day12】数组操作方法及String规则和方法
  • Linux(CentOS)安装 Nginx
  • 4G核心网的演变与创新:从传统到虚拟化的跨越
  • 青少年编程与数学 02-009 Django 5 Web 编程 03课题、项目结构
  • Dify Ollama本地私有化模型实践
  • 数据表中的视图操作
  • 编译原理面试问答
  • [权限提升] Linux 提权 维持 — 系统错误配置提权 - 通配符(ws)注入提权
  • 面试真题 | Momenta c++
  • 【大模型】硅基流动对接DeepSeek使用详解
  • 安当SLA操作系统登录双因素认证:全方位保障Windows系统登录安全
  • 【批量获取图片信息】批量获取图片尺寸、海拔、分辨率、GPS经纬度、面积、位深度、等图片属性里的详细信息,提取出来后导出表格,基于WPF的详细解决方案
  • 如何在Windows中配置MySQL?
  • 2. Mellanox 网卡的参数调优-LINK_TYPE_P1(GPU-AI-大模型,底层调优-测试)
  • 模型压缩 --学习记录2
  • 疯狂前端面试题(二)
  • 算法与数据结构(搜索旋转排序数组)
  • LLM应用实践(1)- 物流状态判断
  • c/c++蓝桥杯经典编程题100道(13)杨辉三角
  • Maven 中常用的 scope 类型及其解析
  • ubuntu24.04安装布置ros
  • 在亚马逊云科技上云原生部署DeepSeek-R1模型(上)
  • Vue 过渡动画实现全解析:打造丝滑交互体验
  • 电脑远程控制vivo手机,切换按钮就能让vivo仅投屏、不受控制!
  • DevOps :无价值指标与可操作指标
  • PHP点餐小程序