C++:string类(1)

news2024/11/13 16:18:18

1.标准库中的string类

1.1 string类(了解)

string类的文档介绍

在使用string类时,必须包含#include头文件以及using namespace std;

1.2 auto和范围for

auto关键字

·用auto声明指针类型时,用auto和auto*没有任何区别,但用auto声明引用类型时则必须加&

·当在同一行声明多个变量时,这些变量必须是相同的类型,否则编译器将会报错,因为编译器实际
·只对第一个类型进行推导,然后用推导出来的类型定义其他变量。

·auto不能作为函数的参数,可以做返回值,但是建议谨慎使用

·auto不能直接用来声明数组
#include<iostream>

using namespace std;

int func1()
{
 return 10;
}

// 不能做参数

void func2(auto a)
{}
// 可以做返回值,但是建议谨慎使用

auto func3()
{
 return 3;
}

int main()
{
 int a = 10;
 auto b = a;
 auto c = 'a';
 auto d = func1();
 // 编译报错:rror C3531: “e”: 类型包含“auto”的符号必须具有初始值设定项

 auto e;
 cout << typeid(b).name() << endl;
 cout << typeid(c).name() << endl;
 cout << typeid(d).name() << endl;
 int x = 10;
 auto y = &x;
 auto* z = &x;
 auto& m = x;
 cout << typeid(x).name() << endl;
 cout << typeid(y).name() << endl;
 cout << typeid(z).name() << endl;
 auto aa = 1, bb = 2;
 // 编译报错:error C3538: 在声明符列表中,“auto”必须始终推导为同一类型

 auto cc = 3, dd = 4.0;
 // 编译报错:error C3318: “auto []”: 数组不能具有其中包含“auto”的元素类型

 auto array[] = { 4, 5, 6 };
 return 0;
}

 auto作为自动识别类型,可以替代较长的定义类型

如:

#include<iostream>
#include <string>
#include <map>

using namespace std;

int main()
{
 std::map<std::string, std::string> dict = { { "apple", "苹果" },{ "orange", 

"橙子" }, {"pear","梨"} };
 // auto的用武之地

 //std::map<std::string, std::string>::iterator it = dict.begin();

 auto it = dict.begin();
 while (it != dict.end())
 {
 cout << it->first << ":" << it->second << endl;
 ++it;
 }
}

范围for

对于一个有范围的集合而言,由程序员来说明循环的范围是多余的,有时候还会容易犯错误。因此C++11中引入了基于范围的for循环。for循环后的括号由冒号“ :”分为两部分:

(1)第一部分是范围 内用于迭代的变量,(2)第二部分则表示被迭代的范围,自动迭代,自动取数据,自动判断结束。 范围for可以作用到数组和容器对象上进行遍历 范围for的底层很简单,容器遍历实际就是替换为迭代器,这个从汇编层也可以看到。

//3.范围for
// auto 替换长类型,但一定程度下失去了可读性
//字符赋值,自动迭代,自动判断结束
//底层就是迭代器
//这个改变不了ch是一个拷贝值,改变拷贝值,不变,加了引用就可以改变了
//for (auto& ch : s2)拷贝
void fun1()
{
    for (auto& ch : s2)//引用
    {
    	cout << ch << " ";
    }
    cout << endl;
    //范围for适用于容器和数组
    int arry[] = { 1,2,3,3 };
    for (auto& e : arry)
    {
    	cout << e << endl;
    }
}
//2.迭代器
//begin()第一个字符的迭代器,s2.end()最后一个位置的下一个位置即是“\0”的迭代器
//迭代去修改可以改变初始值
void fun2()
{
    string s2("hello");
    string::iterator it = s2.begin();
    while (it != s2.end())
    {
    	cout << *it << " ";
    	it++;
    }
}
//四种迭代器
//literator
//reserver_literator
//const_literator
//const_reserver_literator

两者具有相同的原理,否是通过迭代器从begin()找到end();(底层原理相同)

1.3string类的常用接口

1. string类对象的常见构造

void Teststring()
{
    string s1;                // 构造空的string类对象s1

    string s2("hello bit");   // 用C格式字符串构造string类对象s2

    string s3(s2);            // 拷贝构造s3

}

2. string类对象的容量操作

函数名称函数名称 功能说明
size返回字符串有效字符长度(包括'\0')
length返回字符串有效字符长度
capacity返回空间总大小
empty (重点)检测字符串释放为空串,是返回true,否则返回false
clear (重点)清空有效字符
reserve (重点)为字符串预留空间**
resize (重点)将有效字符的个数该成n个,多出的空间用字符c填充
1. size()与length()方法底层实现原理完全相同,引入size()的原因是为了与其他容器的接
口保持一致,一般情况下基本都是用size()。

2. clear()只是将string中有效字符清空,不改变底层空间大小。

3. resize(size_t n) 与 resize(size_t n, char c)都是将字符串中有效字符个数改变到n个,不
同的是当字符个数增多时:resize(n)用0来填充多出的元素空间,resize(size_t n, char 
c)用字符c来填充多出的元素空间。注意:resize在改变元素个数时,如果是将元素个数
增多,可能会改变底层容量的大小,如果是将元素个数减少,底层空间总大小不变。

4. reserve(size_t res_arg=0):为string预留空间,不改变有效元素个数,当reserve的参
数小于string的底层空间总大小时,reserver不会改变容量大小。
void Teststring1()
{
	// 注意:string类对象支持直接用cin和cout进行输入和输出
	string s("hello, bit!!!");
	cout << s.size() << endl;
	cout << s.length() << endl;
	cout << s.capacity() << endl;
	cout << s << endl;

	// 将s中的字符串清空,注意清空时只是将size清0,不改变底层空间的大小
	s.clear();
	cout << s.size() << endl;
	cout << s.capacity() << endl;

	// 将s中有效字符个数增加到10个,多出位置用'a'进行填充
	// “aaaaaaaaaa”
	s.resize(10, 'a');
	cout << s.size() << endl;
	cout << s.capacity() << endl;

	// 将s中有效字符个数增加到15个,多出位置用缺省值'\0'进行填充
	// "aaaaaaaaaa\0\0\0\0\0"
	// 注意此时s中有效字符个数已经增加到15个
	s.resize(15);
	cout << s.size() << endl;
	cout << s.capacity() << endl;
	cout << s << endl;

	// 将s中有效字符个数缩小到5个
	s.resize(5);
	cout << s.size() << endl;
	cout << s.capacity() << endl;
	cout << s << endl;
}
//reserve
void Teststring2()
{
	string s;
	// 测试reserve是否会改变string中有效元素个数
	s.reserve(100);
	cout << s.size() << endl;
	cout << s.capacity() << endl;

	// 测试reserve参数小于string的底层空间大小时,是否会将空间缩小
	s.reserve(50);
	cout << s.size() << endl;
	cout << s.capacity() << endl;
}

3. string类对象的访问及遍历操作

 begin()返回第一个字符的迭代器

end()返回最后一个字符的后一个字符的后一个的理论元素的迭代器

rbegin()返回最后一个字符的迭代器

rend()返回第一个字符的前一个字符的后一个的理论元素的迭代器

4. string类对象的修改操作

函数名称功能说明
push_back在字符串后尾插字符c
append在字符串后追加一个字符串
operator+= (重 点)在字符串后追加字符串str或字符
c_str(重点)返回C格式字符串(遇到'\0'停止)
find + npos(重 点)从字符串pos位置开始往后找字符c,返回该字符在字符串中的 位置,找不到返回npos(-1)
rfind从字符串pos位置开始往前找字符c,返回该字符在字符串中的 位置
substr在str中从pos位置开始,截取n个字符,然后将其返回
1. 在string尾部追加字符时,s.push_back(c) / s.append(1, c) / s += 'c'三种的实现方式差
不多,一般情况下string类的+=操作用的比较多,+=操作不仅可以连接单个字符,还可
以连接字符串。

2. 对string操作时,如果能够大概预估到放多少字符,可以先通过reserve把空间预留
好。

5. string类非成员函数


void test9()
{
	//使用cin>>str的话不能输入空格,要使用getline
	string str;
	getline(cin, str);
	//getline(cin, str, '*');//遇到*号才终止
	size_t pos = str.rfind(' ');
	cout << str.size() - 1 - pos << endl;
}

 

6. vs和g++下string结构的说明

注意:下述结构是在32位平台下进行验证,32位平台下指针占4个字节。

vs下string的结构

string总共占28个字节,内部结构稍微复杂一点,先是有一个联合体,联合体用来定义

string中字符串的存储空间:

·当字符串长度小于16时,使用内部固定的字符数组来存放 
·当字符串长度大于等于16时,从堆上开辟空间

 
union _Bxty

{ // storage for small buffer or pointer to larger one

 value_type _Buf[_BUF_SIZE];
 pointer _Ptr;
 char _Alias[_BUF_SIZE]; // to permit aliasing

} _Bx;

这种设计也是有一定道理的,大多数情况下字符串的长度都小于16,那string对象创建 好之后,内部已经有了16个字符数组的固定空间,不需要通过堆创建,效率高。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2092509.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

gdb 教程

文章目录 GDB启动 GDB 的方法GDB 命令工具参考 GDB GDB是Linux下的调试工具&#xff0c;可以调试C、C、Go、java等语言 GDB提供了以下四个功能&#xff1a; 程序启动时&#xff0c;可以按照自定义的要求运行程序&#xff0c;如设置参数和环境变量可以让被调试的程序在所指定…

Netflix Feign:微服务HTTP调用如何简化?

Netflix Feign&#xff1a;微服务HTTP调用如何简化&#xff1f; 1、什么是Netflix Feign&#xff1f;2、Feign的优点3、示例4、总结 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 1、什么是Netflix Feign&#xff1f; Feign是一个声明式的…

MFC工控项目实例之十添加系统测试对话框

承接专栏《MFC工控项目实例之九选择下拉菜单主界面文本框显示菜单名》 参考前期我的博客文章《MFC3d立体按钮制作》 这里只给出相关代码 1、在SysTest.h文件中添加代码 #include "ShadeButtonST.h" #include "BtnST.h" class CSysTest : public CDialog {…

OpenAI“草莓”模型及全能型与专业型AI的思考

一、OpenAI“草莓”模型的全能性及其未来趋势 近日&#xff0c;OpenAI预计在秋季推出的代号为“草莓”的新AI模型&#xff0c;展现了其在自然语言处理&#xff08;NLP&#xff09;和深度学习领域的又一重大突破。该模型不仅增强了推理能力&#xff0c;还提供了更为人性化的互动…

穿越Java世界的继承奇旅:从基类到子类的华丽蜕变

1.为什么要继承 2.什么是继承以及继承的方式 3.继承的一些语法 4.父类成员的访问 5.关键字super 6.关键字protected 7.关键字final 8.继承与组合 一&#xff1a;为什么要继承 ①代码重用&#xff1a;继承允许我们重用、扩展或修改父类的属性和方法&#xff0c;而无需重…

<Rust>egui学习之小部件(四):如何在窗口中添加滚动条Scroll部件?

前言 本专栏是关于Rust的GUI库egui的部件讲解及应用实例分析&#xff0c;主要讲解egui的源代码、部件属性、如何应用。 环境配置 系统&#xff1a;windows 平台&#xff1a;visual studio code 语言&#xff1a;rust 库&#xff1a;egui、eframe 概述 本文是本专栏的第四篇博…

【C++ Primer Plus习题】7.10

问题: 解答: #include <iostream> using namespace std;double add(double a, double b) {return a b; }double mul(double a, double b) {return a * b; }double sub(double a, double b) {return a - b; }double div(double a, double b) {return a / b; }double cal…

[LLM]:大模型(Transformer)参数量分析

1. 前言2. 模型参数量 文章内容主要摘自&#xff1a;https://zhuanlan.zhihu.com/p/624740065 1. 前言 最近&#xff0c;OpenAI推出的ChatGPT展现出了卓越的性能&#xff0c;引发了大语言模型(Large Language Model, LLM)的研究热潮。大规模语言模型的“大”体现在两个方面&am…

Python编码系列—Python代码重构:提升代码质量

&#x1f31f;&#x1f31f; 欢迎来到我的技术小筑&#xff0c;一个专为技术探索者打造的交流空间。在这里&#xff0c;我们不仅分享代码的智慧&#xff0c;还探讨技术的深度与广度。无论您是资深开发者还是技术新手&#xff0c;这里都有一片属于您的天空。让我们在知识的海洋中…

Leetcode面试经典150题-151.反转字符串中的单词

class Solution {public String reverseWords(String s) {/**先trim一下去掉前后的空格*/String str s.trim();/**转成字符数组 */char[] sArr str.toCharArray();/**先整体倒置*/int l 0;int r sArr.length - 1;reverse(sArr, l, r);/**然后每个单词中逆序 */int left 0;…

SAM 提示框和 Unet的语义分割的融合:自动驾驶车道线分割

1、前言 最近SAM 模型复现的多了&#xff0c;看了不少官方的源码&#xff0c;尝试下SAM和Unet的结合 SAM的提示分割&#xff0c;其实就是在分割的时候&#xff0c;为数据增加一个提示信息&#xff0c;可以是框&#xff0c;点&#xff0c;或者文本等等。这样大模型网络就可以根…

【Python】简单的爬虫抓取

效果&#xff1a;抓取某个学校网站的教授名录&#xff0c;并获取研究方向。 由于网站使用的都是明文&#xff0c;所以抓起来没什么难度&#xff0c;且平时访问量小&#xff0c;很值得用来练习。 代码如下&#xff0c;解释请见注释 import timeimport requests from bs4 impor…

RN开发问题

1、滚动项定位错误 ERROR Invariant Violation: scrollToIndex should be used in conjunction with getItemLayout or onScrollToIndexFailed, otherwise there is no way to know the location of offscreen indices or handle failures. 原因&#xff1a;已修复&#xff0c…

求一个使用C语言将重力加速度gx,gy,gz积分获取到速度的代码

&#x1f3c6;本文收录于《CSDN问答解惑-专业版》专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收…

完整指南:CNStream流处理多路并发框架适配到NVIDIA Jetson Orin (一) 依赖库编译、第三方库编译安装

目录 1 jetson-ffmpeg的编译安装与配置--用来做视频编码、视频解码 2 CV-CUDA库的编译安装与配置--用来做图像缩放、裁剪、色域转换 3 cuda cudnn TensorRT相关库的拷贝与配置 3.1将cuda cudnn TensorRT相关的头文件拷贝到工程中 3.2 将cuda cudnn TensorRT相关的库拷贝到…

docker实战基础一

一、docker安装 # step 1: 安装必要的一些系统工具 yum install -y yum-utils device-mapper-persistent-data lvm2 # Step 2: 添加软件源信息 yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo # Step 3: 更新并安装 Doc…

FlowUs:强大图表功能与多维表结合,开启便捷办公新时代

在当今数字化办公的浪潮中&#xff0c;我们一直在寻找一款能够高效整合数据、清晰呈现信息的工具。而 FlowUs 以其强大的图表功能结合多维表的能力&#xff0c;为我们带来了前所未有的便捷体验。 一、多维表&#xff1a;数据管理的强大基石 FlowUs 的多维表功能就像是一个数据魔…

016_Save_the_picture_in_Matlab中保存图片

图片文件 Matlab核心功能包括出图&#xff0c;印刷质量的图片输出是Matlab核心竞争力之一&#xff0c;matplotlib疯狂追赶&#xff0c;但还是差距明显。出图的含义就是&#xff1a;打印或者导出图形窗体的内容&#xff0c;可供后续使用。在Matlab中&#xff0c;这个行为被定义…

弗洛伊德(Floyd)算法(C/C++)

弗洛伊德算法&#xff08;Floyds algorithm&#xff09;&#xff0c;又称为弗洛伊德-沃尔什算法&#xff08;Floyd-Warshall algorithm&#xff09;&#xff0c;是一种用于在加权图中找到所有顶点对之间最短路径的算法。这个算法适用于有向图和无向图&#xff0c;并且可以处理负…

[YM]课设-C#-WebApi-Vue-员工管理系统 (五)登录

分析&#xff1a; 请求路径&#xff1a;/login 请求方式&#xff1a;POST 接口描述&#xff1a;该接口用于员工登录Tlias智能学习辅助系统&#xff0c;登录完毕后&#xff0c;系统下发JWT令牌。 > api文档中提到JWT令牌 这个相对来说比较复杂 是用来加密&#xff0c;…