C++学习之路(二)

十一、 表达式

如果处于某种原因,要将一条语句放到两行中,可以在第一行末尾添加反斜杠 \,否则会出错。
左值通常是内存单元,右值可以使内存单元的内容。
因此所有的左值都可用作右值,但并非所有的右值都可用作左值。
例如365 = year; 不合理

逻辑运算符合按位运算的差别在于,按位运算符返回的并不是布尔值,而是对操作数对应位执行指定运算的结果。

移位运算符(<<、>>)将整个位序列向左或向右移动,其用途之一是将数据乘以或除以2n

三目操作符:
?:
例如:
int max = (num1 > num2) ? num1 : num2;
等同于:

int max;
if (num1 > num2)
{max = num1;}
else
{max = num2;}

基于范围的for循环

for (VarType varNmae : sequence)
{}

例如给定一个数组:

int someNums[] = {1, 2, 3};
for (int a : someNums)
cout << a << endl;

就可以把数组的每个元素输出。

十二、标准模板库

1、顺序容器

顺序容器按照顺序存储数据,如数组和列表。顺序容器具有插入速度快但查找操作相对较慢的特征。

  • std::vector :操作和动态数组一样,在最后插入数据;可将vector看做书架,可在一段添加和拿走图书。
  • std::deque :与std::vector类似,但允许在开头插入好热删除元素。
  • std::list : 操作和双向链表一样。可看做链条,对象被连接在一起,可以在任何位置添加或者删除对象。
  • std::forward_list :类似于std:list,但是单向链表,只能沿着一个方向遍历。

2、关联容器

关联容器按指定的顺序存储数据,就像字典一样。这将降低插入数据的速度,但在查询方面有很大的优势。

  • std::set : 存储各不相同的值,在插入时进行排序;容器的复杂度为对数。
  • std::unordered_set :存储各不相同的值,在插入时排序;容器的复杂度为常数。这种容器是c++11新增的。
  • std::map : 存储键-值对,并根据唯一的键排序;容器的复杂度为对数。
  • std::unordered_map :存储键-值对,并根据唯一的键排序;容器的复杂度为对数。
  • std::multiset :与set类似,但允许存储多个值相同的项,即值不需要是唯一的。
  • std::unordered_multiset :与unordered_set类似,但允许存储多个值相同的项,即值不需要是唯一的。
  • std::multimap:与map类似,但是不要求键是唯一的。
  • std::unordered_multimap:与unordered_map类似,但不要求键是唯一的。

3、容器适配器

容器适配器是顺序容器和关联容器的变种,其功能有限,用于满足特定的需求。

  • std::stack :以LIFO(last in first out 后进先出)的方式存储元素,让我们能在栈顶插入和删除元素。
  • std::queue:以FIFO(first in first out 先进先出)的方式存储元素,让我们能删除最先插入的元素。
  • std::priority_queue:以特定顺序存储元素,因为优先级最高的元素总是在队列的开头。

4、迭代器

迭代器是一种检查容器内元素并遍历元素的数据类型。可以替代下标访问vector对象的元素。每种容器类型都定义了自己的迭代器类型,如 vector:
vector::iterator iter;
上述语句定义了一个名为 iter 的变量,它的数据类型是 vector< int > 定义的 iterator 类型。每个标准库容器类型都定义了一个名为 iterator 的成员,这里的 iterator 与迭代器实际类型的含义相同。

(1)STL string 类

拼接字符串

sting sampleStr1 ("Hello");
string sampleStr2 ("String");
sampleStr1 += sampleStr2;
或
sampleStr1.append(sampleStr2);
都可以把"Hello"和"String" 链接起来。

查找

size_t charPos = sampleStr.find ("day", 0);
if (charPos != string :: npos)
cout ....
else
cout ....

size_t在32位架构上是4字节,在64位架构上是8字节,在不同架构上进行编译时需要注意这个问题。而int在不同架构下都是4字节,与size_t不同;且int为带符号数,size_t为无符号数。
ssize_t是有符号整型,在32位机器上等同与int,在64位机器上等同与long int.

size_t一般用来表示一种计数,比如有多少东西被拷贝等。例如:sizeof操作符的结果类型是size_t,该类型保证能容纳实现所建立的最大对象的字节大小。 它的意义大致是“适于计量内存中可容纳的数据项目个数的无符号整数类型”。所以,它在数组下标和内存管理函数之类的地方广泛使用。
而ssize_t这个数据类型用来表示可以被执行读写操作的数据块的大小.它和size_t类似,但必需是signed.意即:它表示的是signed size_t类型的。

截断
erase()

string sampleStr ("Hello String! Wake up to a beautiful day !);
sampleStr.erase (13, 28); // 删除从第13个到第28个字符。

sampleStr.erase(iCharS); //删除指定的字符 iCharS = ...

sampleStr.erase (sampleStr.begin (), sampleStr.end());

反转

string sampleStr ("Hello String! We will recerse you!);
reverse (sampleStr.begin (), sampleStr.end());

(2) STL 动态数组

vector
要实例化vector,需要指定要在该动态数组中存储的对象类型:

std ::vector dynIntArray;
std::vectordynFloatArray;
std::vectordynTunaArray;

使用push_back()在末尾插入元素

vector integers;
integers.push_back(8);

列表初始化:

vector integers = {50,1,85,101};
或者
vectorintegers {50,1,85,101}

使用insert()在指定位置插入元素

integers.insert(integers.end(),2,5); //在末尾插入两个5

删除vector中的元素
使用pop_back()删除末尾的元素。

理解大小和容量
vector的大小指的是实际存储的元素数,而vector的容量指的是在重新分配内存以存储更多元素前vector能够存储的元素数。因此,vector的大小 <= 容量。
我的理解: vector就像一个可以变化大小的水桶,一开始装10L的水,大小和容量都是10,现在把水倒了 装5L 那么大小就是5 容量还是10 ,再倒了 装20L的水,那么大小和容量都是20L。

查询大小
cout << "size: " << integers.size () << endl;

查询容量:
cout << "capacity" << integers.capacity() << endl;

deque
与vector非常相似,但支持在数组开头和末尾插入或删除元素。用push_front()和pop_front()

(3)STL list 和 forward_list

list是双向链表,优点主要是,插入和删除元素的速度快,且时间是固定的。
forward_list 是单向链表,只能沿着一个方向遍历。

实例化list

std::list linkInts;
std::list listFloats;
std:listlistTuna;
要声明一个指向list中元素的迭代器,可以这样做:
std::list::const_iterator elementInList;

和deque类似,要在list开头或者末尾插入元素,可使用,push_front(),push_back()

forward_list
插入元素只能用push_front(),而不能使用push_back()

(4) STL 集合类

容器set和multiset让程序员能够在容器中快速查找键,键是存储在一维容器中的值。set和multiset之间的区别在于,后者可以存储重复的值,而前者只能存储唯一的值。

为了实现快速搜索,STL set和multiset的内部结构像二叉树,这意味着将元素插入到set或multiset时将对其进行排序,以提高查找速度。

实例化std::set对象

类似于之前的

查找

auto elementFound = setInts.find(-1);
if (elementFOund != setInts.end())
{
cout......
}

(5) STL 映射类

map和multimap之间的区别在于,后者能够有存储重复的键,前者只能存储唯一的键
实例化map

#include 
using namespace std;
...
map > mapObj;
multimap > mapObj;
第三个参数是可选的,如果指定了键和值的类型,而省略了第三个模板的参数,将默认升序。
例如:
std :: map mapIntTostr;
std :: multimap  mmapIntToStr;

十三、lambda表达式

lambda表达式是一种定义匿名函数对象的简洁方式,是c++11新增的。
定义lambda表达式
lambda表达式定义必须以方括号打头[ ]。这些括号告诉编译器,接下来是一个lambda表达式。方括号后面是一个参数列表,该参数列表与不使用lambda表达式时提供给operator()的参数列表相同。
[](type paraname) { }

你可能感兴趣的:(c++)