C++

19-11-3-C++primer-基础学习3

C++

Posted by Wangchenchen on 2019-11-03

上一篇对基础部分的变量,基本类型,简单类,多个关键字进行了介绍,这篇主要是对里面的标准库类型 进行相关的总结:

c++除了定义基本数据类型还定义了内容丰富的抽象数据类型标准库;

命名空间的using声明:

​ using:可以在不需要加前缀的情况下直接访问命名空间的成员;

使用前:

1
2
3
int main(){
std::cout<<"output content"<<std::end1;
}

使用后:

1
2
3
4
5
6
7
8
using std::cout;
using std::cin;
using std::end1;
int main(){
int v1;
cout << "output content " <<end1;
cin >> v1;
}
using和typedef的区别:

​ using是扩展typedef而来的,而typedef是延申自c语言,前面有介绍typedef,它就是个高阶版的defind,using可以用模板,typedef是不可以的,在c++中也是很推荐使用模板;

标准库string类型:

​ string 类型支持长度可变的字符串,而标准库就是负责管理与存储字符相关的内存,以及提供各种有用的操作。string标准库基本满足对字符的所有操作;

​ 使用前需要引用库,如下:

1
2
#include <String>
using std::string
对象的定义和初始化:

​ string 标准库支持几个构造函数,如下:

1
2
3
4
String s1; 			//默认构造函数,s1 为空串
String s2(s1); //将s2初始化为s1的一个副本
String s3("value") //将s3 =初始化为一个字符串字面值副本
String s4(n,'c') //将S4初始化为字符'c'的n个副本;
string的输入输出:

直接上例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <String>
using std::string
using std::cin;
using std::cout;
using std::cin;
int main(){
/*声明*/
String s;
/*输入*/
while(cin >> s){
cout << s << endl;
}

}
string对象的操作:
1
2
3
4
String s;
s = "content";
s.empty() //如果s为空就返回true,否则就返回false;
s.size() //返回 s 的字符个数
string::size_type 类型:

​ 正常来说size(),返回的内容应该用一个整型来接,也就是我们前面说的无符号整型,但是事实上,操作返回的是 string::size_type类型的值;

​ string类型和其他库类型都定义了一些配套类型(companion type)。通过这些配套类型,库类型的使用就能与机器无关,size_type就是这些配套类型中的一种,不过在使用时必须加上string作用域操作符;

​ 最后重复一遍:不要把size() 返回值赋值给int类型,不要把size() 返回值赋值给int类型,不要把size() 返回值赋值给int类型

string关系操作符:

​ string 类定义几种关系操作符来比较两个string大小.这些操作符实际上是比较每个string对象的字符;

1
2
3
4
String s1 = "Hello";
String s2 = "Hallo";
String s3 = "Hello world";
String s4 = "HelloWorld";

上面的四个内容,s1 < s2; s3 != s4; 不过对于对象并不推荐直接使用操作符对里面的内容进行直接的比较,因为“==”是对地址的比较,基本上这些库都会对里面的内容定义比较的函数,如string,比较两个string的大小时直接使用s.compare();

string 拼接:

​ ”+“ 使用+时左值和右值都必须是string类型;

1
2
3
4
String s1 = "abc";
String s2 = "def";
String s3 = s1 + s2; //s3 是 abcdef
String s4 = s2 += s1 //将s1直接添加到s2的末尾;
string 对象获取字符:
1
2
3
4
String s1("some sthing");
for(string::size_type ix = 0; ix != s1.size();++ix){
cout << s1[ix] <<end1;
}
string 中一些字符的处理:
1
2
3
4
5
6
7
8
9
10
11
12
13
isalnum(s);			//如果c是字母或数字,则为true;
isalpha(s); //如果c是字母,则为true;
iscntrl(s); //如果c是控制字符,则为true;
isdigit(s); //如果c是数字,则为true;
isgraph(s); //如果c不是空格,但可以打印,则为true;
islower(s); //如果c是小写的字母,则为true;
isprint(s); //如果c是可打印的字符,则为true;
ispunct(s); //如果c是标点符号,则为true;
isspace(s); //如果c是空白符号,则为true;
isupper(s); //如果c是大写字母,则为true;
isxdigit(s); //如果c是十六进制数,则为true;
tolower(s); //如果c是大写字母,则返回其小写字母形式,否则直接返回c;
toupper(s); //如果c是小写字母,则返回其大写字谜形式,否则直接返回c;
标准库vector类型:

​ vector是同一种类型的对象的集合,每个对象都有对应的整数索引值,标准库将负责管理和存储元素相关的内存;vector是一个容器,在使用前引头文件;

1
2
#include <vector>
using std::vector;
vector定义和初始化:
1
2
3
4
5
6
7
8
9
vector<T> v1;			//vector 保存类型为T的对象,默认构造函数为空。
vector<T> v2(v1); //v2 是 v1 的副本
vector<T> v3(n,i); // v3 包含那个值为i的元素
vector<T> v4(n); //v4 含有值初始化的元素的n个副本

/*错误示范*/
vector<int> ivec1;
vector<int> ivec2(ivec1); //正确,
vector<string> ivec3(ivec1); //错误,类型不一样,复制的类型要一样;
vector返回值:

vector返回的是size_type类型;

vector通过下标,添加元素:
1
2
3
4
5
6
7
8
string word;
vector<String> text;
while(cin >> word){
text.push_back(word); //添加元素;
}
for(vector<String>::size_type ix = 0; ix != text.size();++iv){
text[ix] = 0;
}
拓展, vector和其他容器的区别:

​ List封装了链表,Vector封装了数组, list和vector得最主要的区别在于vector使用连续内存存储的,他支持[]运算符,而list是以链表形式实现的,不支持[]。

​ Vector对于随机访问的速度很快,但是对于插入尤其是在头部插入元素速度很慢,在尾部插入速度很快。List对于随机访问速度慢得多,因为可能要遍历整个链表才能做到,但是对于插入就快的多了,不需要拷贝和移动数据,只需要改变指针的指向就可以了。另外对于新添加的元素,Vector有一套算法,而List可以任意加入。
​ Map,Set属于标准关联容器,使用了非常高效的平衡检索二叉树:红黑树,他的插入删除效率比其他序列容器高是因为不需要做内存拷贝和内存移动,而直接替换指向节点的指针即可。
​ Set和Vector的区别在于Set不包含重复的数据。Set和Map的区别在于Set只含有Key,而Map有一个Key和Key所对应的Value两个元素。
​ Map和Hash_Map的区别是Hash_Map使用了Hash算法来加快查找过程,但是需要更多的内存来存放这些Hash桶元素,因此可以算得上是采用空间来换取时间策略

迭代器简介:

​ 在访问vector 时,我用的是下标但是还有其他的办法,就是用迭代器了(iterator),迭代器是一种检查容器内元素并遍历元素的数据类型;

iterator类型:

​ 每个容器类型都定义了自己的迭代器类型,如vector:

​ vector::iterator iter;

​ 每个标准库容器类型都定义了一个名为iterator的成员,上面的意思是 :定义了一个名为iter的变量,数据类型由vector定义;

begin和end操作:
1
2
vector<int>::iterator iter = ivec.begin(); //返回的迭代器指向第一个元素;
ivec.end(); //指向下 "末端元素的下一个";

end 说白了不是指向任何一个实际的元素,它只是起一个哨兵的作用;

自增和解引用:

​ *iter ;其实这个就等于 iter[0];,如果需要自加,直接 ++iter 就好;

实例:
1
2
3
for(vector<int>::iterator iter = ivec.begin(); iter != ivec.end(); ++iter){
*iter = 0;
}
const_iterator:

它只能够读不支持对返回迭代器的写操作;

1
2
3
for(vertor<String>::const_iterator iter = ivec.begin();iter != ivec.end(); ++ivec){
cout << *iter << end1;
}
结语:

​ 这篇主要对string,vector和iterator及进行了详细的解释,下面一篇将对数组和指针进行解释,如果发现有什么地方写的不好,还希望您能留下宝贵的意见,非常感谢~

E-mail : jsntwangchenchen@outlook.com 王晨晨