1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > 【C++笔记】字符串 向量和数组

【C++笔记】字符串 向量和数组

时间:2019-06-13 19:20:42

相关推荐

【C++笔记】字符串 向量和数组

string(C++Primer 5th)

string & vector

string表示可变长的字符序列,vector存放的是某种给定类型对象的可变长序列。

using声明

头文件不应包含using声明,否则头文件的内容会拷贝到所有引用它的文件中去。

string初始化赋值

使用等号=初始化的是拷贝初始化,不使用等号的称为直接初始化。

size()函数的返回值是类型size_type,无符号整数型。如果n是负值的int,则s.size()

string s(10,'c');// s的内容是cccccccccccin>>word; // 遇到空格停止getline(cin,line); // 读入一整行,直到换行符auto len = line.size(); // len的类型是string::size_typestring s1 = s + "," + "world"; // 加法需保证+两次的运算对象至少有一个是string string s2 = "hello" + "," + s1; // 错误:两个运算对象都不是string

使用C++版本的C标准库头文件

一般来说,C++程序应该使用名为cname的头文件而不使用name.h的形式。

基于范围的for语句

// 统计string对象中标点符号的个数string s("Hello World!!!");decltype(s.size()) punct_cnt=0; // 用于统计个数,无符号整型确保下标不小于0 for(auto c:s)if(ispunct(c)) punct_cnt++;

// 使用范围for语句改变字符串中的字符string s("Hello World!!!");for(auto &c:s)c = toupper(c); // 将string对象转换成大写cout << s << endl;

vector

vector概念

标准库类型vector表示对象的集合,其中所有对象的类型都相同,通常也称容器。

vector是模板而非类型,由vector生成的类型必须包含vector中元素的类型,如vector<int>、vector<vector<int>>

由于引用不是对象,所以不存在包含引用的vector。

列表初始化 OR 元素数量

vector<int> v1(10); // v1有10个元素,每个的值都是0vector<int> v2{10}; // v2有1个元素,该元素的值是10vector<int> v3(10,1); // v3有10个元素,每个的值都是1vector<int> v4{10,1}; // v4有2个元素,值分别是10和1vector<string> v5{"hi"}; // v5有一个元素"hi"vector<string> v6("hi"); // 错误,不能用字符串字面值构建vector对象vector<string> v7{10};// v7有10个默认初始化的元素vector<string> v8{10,"hi"}; // v8有10个值为"hi"的元素

向vector对象中添加元素

添加元素的方法是先创建一个空vector,然后在运行时利用vector的成员函数push_back向其中添加元素。PS:预先指定vector对象的容量没有什么必要,反而可能导致性能变差,不建议。

如果循环体内部含有向vector对象添加元素的语句,则不能使用范围for循环!范围for语句体内不应改变其所遍历序列的大小。

vector<int> v; // 空vector对象for(int i = 0; i != 100; i++)v.push_back(i); // 往vector中添加0到99,不能用下标方式添加元素!

/*《C++Primer 5th》P94.练习3.16*/#include <iostream>#include <vector>#include <string>using namespace std;void main(){vector<int> v1, v2(10), v3(10, 42), v4{ 10 }, v5{ 10,42 };vector<string> v6{ 10 }, v7{ 10,"hi" };cout << "v1:"<< endl; for (auto c : v1) cout << c << "\t"; cout << "\n\nv2:" << endl; for (auto c : v2) cout << c << "\t"; cout << "\n\nv3:" << endl; for (auto c : v3) cout << c << "\t"; cout << "\n\nv4:" << endl; for (auto c : v4) cout << c << "\t"; cout << "\n\nv5:" << endl; for (auto c : v5) cout << c << "\t"; cout << "\n\nv6:" << endl; for (auto c : v6) cout << c << "\t"; cout << "\n\nv7:" << endl; for (auto c : v7) cout << c << "\t";getchar();return ;}

迭代器

相比下标运算符

所有标准库容器如vector都可以使用迭代器,但是只有少数几种才同时支持下标运算符。严格来说,string对象不属于容器类型,但它支持迭代器。

begin、end

begin成员负责返回指向第一个元素的迭代器,end成员负责返回尾元素的下一位置(该位置并无元素)的迭代器。end返回的迭代器通常称为尾后迭代器或尾迭代器。

如果容器为空,则begin和end返回的是同一个迭代器即尾后迭代器。

所有标准库容器的迭代器都定义了==和!=,但其中大多数并没有定义<运算符!!!

for(auto it = s.begin(); it != s.end(); ++it) *it = toupper(*it); 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

begin和end返回的具体类型由对象是否是常量来决定,如果对象是常量,begin和end返回const_iterator;如果对象不是常量,返回iterator。

cbegin、cend

C++11新标准引入了cbegin和cend,用法与begin、end相同,不同的是不论vector对象是否常量,返回值都是const_iterator。

解引用与成员访问

it->mem和(*it).mem表达的意思相同。

(*it).empty() // 解引用it,然后调用empty成员*it.empty()// 错误,试图访问it的empty成员(并不存在)for(auto it = text.cbegin(); it != text.cend() && !it->empty(); ++it)cout<< *it <<endl;

difference_type

迭代器的距离是指一个迭代器移动多少位置能追上另一个迭代器,类型位difference_type的带符号整型数,可正可负。

二分搜索

迭代器的经典算法时二分搜索。

数组

数组初始化

定义数组时必须指定数组类型,不允许使用auto关键字由初始值的列表推断类型。和vector一样,数组元素应为对象,因此不存在引用的数组。

// 错误示范const char a[6] = "Daniel"; // 错误,没有空间存放空字符int a[] = {0,1,2}; int a2 = a;// 错误,不允许使用一个数组初始化另一个数组a2 = a; // 错误,不能把一个数组直接赋值给另一个数组

数组声明

int *ptrs[10]; // ptrs是含有10个整型指针的数组int &refs[10] = /*?/;// 错误,不存在引用的数组int (*parray)[10] = &arr; // parray指向一个含有10个整数的数组int (&arrRef)[10] = arr; // arrRef引用一个含有10个整数的数组int *(&array)[10] = ptrs; // arry是数组的引用,该数组含有10个指针

指针也是迭代器

int arr = {0,1,2,3,4,5,6,7,8,9};int *e = &arr[10]; // 指向arr尾元素的下一位置的指针for(int *b = arr; b != e; ++b)// arr表示首元素的地址cout << *b << endl;

说明:arr有10个元素,尾元素所在位置的索引是9,下一位置的不存在的元素用于提供地址初始化e。与尾后迭代器雷系,尾后指针不指向具体的元素,不能进行解引用或是递增操作。

标准库函数begin和end

C++11标准引入了begin和end两个函数,与容器中的成员函数功能相似。但数组不是类类型,所以begin和end不是数组的成员函数,正确的使用形式是将数组作为它们的参数。

int ia[] = {0,1,2,3,4,5,6,7,8,9};int *beg = begin(ia);// 指向ia首元素的指针int *last = end(ia);// 指向arr尾元素的下一位置的指针

指针运算

constexpr = size_t sz =5;int arr[sz] = {1,2,3,4,5};int *ip = arr;int *ip1 = ip + 4; // ip1指向arr的尾元素arr[4]auto n = end(arr)-begin(arr); // n为5,类型为ptrdiff_t带符号类型

如果两个指针分别指向不相关的对象,则不能比较它们。

如果p是空指针,允许给p加上或减去一个值为0的整型常量表达式。两个空指针也允许彼此相减,结果为0。

C风格字符串

cstring

定义在cstring头文件中,cstring是C语言头文件string.h的C++版本。

对大多数应用来说,使用标准库string要比使用C风格字符串更安全、更高效。

string s("hello world"); // string初始化char *str = s; // 错误,不能用string对象初始化char*const char *str = s.c_str(); // 正确,返回C风格的字符串,不改变字符数组内容,改变s的值会使返回的数组失效

使用数组初始化vector对象

int int_arr[] = {0,1,2,3,4,5};vector<int> ivec(begin(int_arr),end(int_arr));

遍历多维数组

要使用范围for语句处理多维数组,除了最内层的循环外,其他所有循环的控制变量都应该是引用类型。

size_t cnt =0;for(auto &row : ia) // for(auto row : ia )错误,自动转换成ia首元素的指针for(auto &col : row) // for(auto col : row)也正确{col = cnt;++cnt;}for(auto p = begin(ia); p != end(ia); ++p)for(auto q = begin(*p); q != end(*p); ++q)cout << *q << ' ';

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。