C++知识总结(2)--字符串和数组
标准库类型string
标准库类型string表示可变长的字符序列。
使用string
类型需要先添加头文件#include<string>
,并且由于其定义在命名空间std
中,所以还要添加using std::string;
。
string初始化的方式有下面几种方式:
其中使用等号的初始化执行的是拷贝初始化,是将等号右侧的初始值拷贝到新创建的对象中;而不使用等号,执行的就是直接初始化。
下面给出了string的大多数操作:
读取操作中,string对象会自动忽略开头的空白(即空格符、换行符、制表符等)并从第一个真正的字符开始读起,直到遇到下一处空白为止。
而如果需要读取一行,则可以使用函数getline,它的参数是一个输入流和string对象,从给定的输入流中读取内容,直到遇到换行符为止,注意它会将换行符也读取进来,但是并不保存到string对象中。
size()函数会返回string对象的长度,其返回值的类型是string::size_type
,它是一个无符号类型的值,而且能够存放任何string对象的大小。
当把string对象和字符字面值及字符串字面值混在一条语句中使用时,必须确保每个加法运算符两侧运算对象至少有一个是string。此外,字符串字面值和string是不同的类型。
在cctype头文件中定义了一组标准库函数用于改变某个字符的特性,具体如下所示:
基于范围的for
语句形式如下所示:
string str("string");
for(auto c : str)cout << c << endl;
上面是利用这个for
语句来输出字符串str
中的每个字符,而如果要改变字符串中的内容,则需要将循环变量定义成引用类型,如下所示:
string str("string");
for(auto &c : str)c = toupper(c);
cout << str <<endl;
上述代码就是将str
中的字符串都变成大写字母,其中关键之处就是auto &c
中使用引用类型。
标准库类型vector
标准库类型vector表示对象的集合,其中所有对象的类型都相同。
要使用vector
,都必须做如下using
声明和添加头文件:
#include<vector>
using std::vector;
C++语言既有类模板,也有函数模板,而vector
是一个类模板。
模板本身不是类或函数,可以将模板看作是编译器生成类或函数编写的一份说明。编译器根据模板创建类或函数的过程称为实例化,当使用模板时,需要指出编译器应把类或函数实例化成何种类型。
对于类模板,需要提供一些额外信息来指定模板到底实例化成什么类,提供的信息总是这样:即在模板名字后面跟一对尖括号,在括号内放上信息。例如,vector<int> ivec;
则是定义了一个保存int
类型的对象ivec
。
vector
可以容纳大多数类型的对象作为其元素,但是因为引用不是对象,所以不存在包含引用的vector
。
初始化vector
的方法如下:
一般初始化的时候,使用的是圆括号,提供的值是用来构建vector
,如上述例子的v3,v4
;而如果使用的是花括号,则一般是表示我们想使用列表初始化vector
对象,但如果提供的值不能进行列表初始化,如vector<string> v{10};
这表示v
有10个默认初始化的元素,或者如vector<string> v{10, "hi"};
这表示v
有10个值为”hi”的元素。
注意,如果循环体内部包含有向vector
对象添加元素的语句,则不能使用范围for
语句,范围for
语句体内不应改变其所遍历序列的大小。
迭代器介绍
迭代器也可以实现下标运算符的功能,即能够访问string
对象的字符或者vector
对象的元素。
迭代器提供 了对对象的间接访问,跟指针不一样的是,获取迭代器不是使用取地址符,有迭代器的类型同时拥有返回迭代器的成员。这些类型都拥有名为begin和end的成员,其中begin成员负责返回指向第一个元素的迭代器,而end成员负责返回指向容器或string
对象“尾元素的下一位置”的迭代器,即其指示的是容器的一个本不存在的尾后元素,因此它也常被称为尾后迭代器。如果容器为空,则begin和end返回的是同一个迭代器。
迭代器的运算符如下:
实际上,跟不知道string
和vector
的size_type
成员到底是什么类型一样,一般来说我们也不知,或者也无需知道迭代器的精确类型。实际上,拥有迭代器的标准库类型使用iterator和const_iterator来表示迭代器的类型,如:
vector<int>::iterator it; // it能读写vector<int>的元素
string::iterator it2; // it2能读写string对象中的字符vector<int>::const_iterator it3; // it3只能读元素,不能写元素
string::const_iterator it4; // it4只能读字符,不能写字符
const_iterator和常量指针差不多,能读取但不能修改它所指的元素值,如果vector
或string
对象是常量,则只能使用const_iterator;相反,iterator的对象可读可写,只有vector
或string
对象不是常量,则这两者都可以使用。
解引用迭代器可获得迭代器所指的对象,如果该对象的类型恰好是类,就有可能希望进一步访问它的成员。如(*it).empty()
,it
是一个vector
对象的迭代器,这句代码就是调用vector
的empty
函数,但是注意这里必须有圆括号,否则点运算符是指向it
,而不是it
解引用的结果。可以使用箭头运算符->实现同样的效果,即it->empty()
,它就是等价于(*it).empty()
。
注意,但凡是使用了迭代器的循环体,都不要向迭代器所属的容器添加元素。
数组
数组是一种复合类型,其声明形如a[d]
,a
是数组名,而d
是数组的维度,维度必须大于0,且必须是一个常量表达式,即编译的时候维度应该是已知的。
和内置类型变量一样,在函数内部定义了某种内置类型的数组,那么默认初始化会令数组含有未定义的值。
不能将数组的内容拷贝给其他数组作为初始值,也不能用数组为其他数组赋值,即下列行为是错误的:
int a[] = {0,1,2}; // 含有3个整数的数组
int a2[] = a; // 错误:不允许使用一个数组初始化另一个数组
a2 = a; // 错误:不能把一个数组直接赋值给另一个数组
在C++中,指针和数组由非常紧密的联系,在使用数组的时候,编译器一般会把它转换成指针。
通常情况下,使用取地址符来获取执行某个对象的指针,取地址符可以用于任何对象,数组的元素也是对象,因此对数组的元素使用取地址符就能得到指向该元素的指针。
此外,数组还有一个特性:在很多用到数组名字的地方,编译器都会自动地将其替换为一个指向数组首元素的指针。如string *p2 = nums;
等价于p2 = &nums[0];
。所以大多数表达式中,使用数组类型的对象其实是使用一个指向该数组首元素的指针。
当使用数组作为一个auto
变量的初始值时,推断得到的类型是指针而非数组。
C++11新标准引入了两个名为begin
和end
的函数,这两个函数与容器中两个同名成员功能类型,不过数组不是类类型,因此这两个函数不是成员函数,正确的使用形式是将数组作为它们的参数。
指向数组元素的指针可以执行一些如解引用、递增、比较、与整数相加、两个指针相减等的迭代器运算。
其中,两个指针相减的结果是它们之间的距离,但两个指针必须指向同一个数组中的元素;而对于比较运算,也要求两个指针指向同一个数组的元素或者该数组的尾元素的下一位置,否则就不能比较;
可以使用数组来初始化vector
对象,只需指明要拷贝区域的首元素地址和尾后地址,如:
int int_arr[] = {0, 1, 2, 3, 4, 5};
// ivec有6个元素,分别是int_arr中对应元素的副本
vector<int> ivec(begin(int_arr), end(int_arr));
// 也可以是数组的一部分,下面是拷贝三个元素:int_arr[1], int_arr[2], int_arr[3]
vector<int> subVec(int_arr+1, int_arr+4);
多维数组其实就是数组的数组。
使用范围for
语句处理多维数组,除了最内层的循环外,其他所有循环的控制变量都应该是引用类型。
C++知识总结(2)--字符串和数组相关推荐
- java字符串与数组比较_Java字符串与数组
问题及答案来源自<Java程序员面试笔试宝典>第四章 Java基础知识 4.5字符串与数组 1.字符串创建与存储的机制是什么? Java中字符串声明与初始化主要有两种情况: (1)Stri ...
- Java基础知识(五) 字符串与数组
Java基础知识 字符串与数组 1. 字符串的创建与存储的机制是什么 2. "==".equals和hashCode有什么区别 3. String.StringBuffer.Str ...
- 【java json基础】字符串转json json转字符串 json数组转换 【java基础知识】【实用】【一看就会】
原文:[java json基础]字符串转json json转字符串 json数组转换 [java基础知识][实用][一看就会] 读书就是:从薄读厚,再从厚读薄的过程. 文比较长,各讲述如下: 若是新手 ...
- c# string 占位符_C# 基础知识系列- 9 字符串的更多用法(一)
0. 前言 在前面的文章里简单介绍了一下字符串的相关内容,并没有涉及到更多的相关内容,这一篇将尝试讲解一下在实际开发工作中会遇到的字符串的很多操作. 1. 创建一个字符串 这部分介绍一下如何创建一个字 ...
- java 字符数组与字符串_用于字符串和数组的5种简单有效的Java技术
java 字符数组与字符串 Java通常会排在前五种最流行的编程语言中,因此可以理解. 它是一种通用语言,非常容易学习,因为它是一种高级语言,并且可以满足许多用例. 由于这些原因,Java是一门很棒的 ...
- 用于字符串和数组的5种简单有效的Java技术
Java通常会排在前五种最受欢迎的编程语言之内,这可以理解. 它是一种通用语言,非常容易学习,因为它是一种高级语言,并且可以满足许多用例. 由于这些原因,Java是一门伟大的语言,可以用来学习您是 ...
- glibc 知:手册05:字符串和数组
文章目录 1. 前言 2. 字符串和数组实用程序 2.1. 字符串的表示 2.2. 字符串和数组约定 2.3. 字符串长度 2.4. 复制字符串和数组 2.5. 连接字符串 2.6. 复制时截断字符串 ...
- 乐鑫esp8266学习rtos3.0笔记第3篇: 一篇文章带你搞掂存储技术 NVS 的认识和使用,如何利用NVS保存整型、字符串、数组以及结构体。(附带demo)
本系列博客学习由非官方人员 半颗心脏 潜心所力所写,不做开发板.仅仅做个人技术交流分享,不做任何商业用途.如有不对之处,请留言,本人及时更改. 1. Esp8266之 搭建开发环境,开始一个" ...
- php 将字符串 变为 数组,php将字符串转换为数组
摘要 腾兴网为您分享:php将字符串转换为数组,作业大师,智能互联,优化大师,学习计时等软件知识,以及京医通挂号app,浩顺云服务,拍照扫描,有道网易词典,freehand,arcgis软件,安卓录音 ...
最新文章
- 视频演示:高颜值免费在线绘图ImageGP
- android 反编译
- oracle按时间点还原数据
- 自动拆箱引发的空指针_02
- Python调用自己写的模块
- 网页的根标记是 html,网页的根标记是,主体标记是_________。
- paip.URL参数压缩64进制
- nginx流媒体服务器性能,搭建nginx流媒体服务器(支持HLS)
- spark学习之执行计划explain
- 文章标签设计方法,文章Tags数据库设计方法举例
- 【华为OD机试真题 JAVA】数字涂色
- 计算机类期刊投稿经验
- Photoshop中27种图层混合模式原理图文详解
- 基于yolov5的目标检测和单目测距
- 文献解读|迁徙蝗虫生理和转录水平的衰老特征
- vue+elementUI上传图片
- 基于Java毕业设计校园社团管理平台源码+系统+mysql+lw文档+部署软件
- 递推最小二乘RLS推导
- 《iOS开发全然上手——使用iOS 7和Xcode 5开发移动与平板应用》之Objective-C新手训练营...
- Value Use User
热门文章
- 华为mate40会不会有鸿蒙系统,鸿蒙OS系统正式推送,拿华为Mate40更新后,发现了优缺点...
- php起始符大全,PHP 符号大全
- C++ 控制结构和函数(三)—— 函数II(Functions II)
- Linux 字符设备驱动结构(二)—— 自动创建设备节点
- 嵌入式GUI FTK支持输入法
- 简单的封装axios 不包含状态码和提示
- js冒泡排序,简单的冒泡排序
- React开发(148):componentWillReceiveProps
- javascript学习系列(24):数组中的substring方法
- [vue] v-model是什么?有什么用呢?