C++Primer 第三章和第四章,第五章
命名空间
命名空间是为了防止命名冲突,但是对于不同的名称的访问,我们需要表明其所在的命名空间,为了简化编写,我们可以使用using关键字来进行声明,这样在使用时,就不用再写前缀,即完整的名字;
//using namespace::name using std::cin int main(){ int i; cin>>i; }
例如我们的基本输入和输出,std::cout, std::cin ,都是与std命名空间,为了简化编写,可以使用using关键字进行声明,使用using声明之后,在之后的调用不需要添加专门的前缀,
注意:头文件一般不要包含using声明,因为头文件在被引用时,有可能会产生命名冲突;
string
string是可变长的字符序列,使用string必须包含string头文件。
#include<string> int main(){ stirng name ="land"; }
string对象的初始化:
string str ; //定义,默认初始化,是一个空字符串; string s1 = str; // 拷贝初始化 string s2 = "land"; // 拷贝初始化 string s3(12,'b'); //值为12个b 直接初始化
直接初始化和拷贝初始化
拷贝初始化:使用等号(=)初始化一个变量,把等号右边的初始值拷贝到新创建的对象中去;
直接初始化:不使用等号;
当初始值只有一个时,使用直接初始化或者拷贝初始化都可以,当初始值要用到多个值,则只能使用直接初始化;
string str = string(23,'n'); //拷贝初始化 等价于: string temp(23,'n'); string str = temp;
string操作
1.是否为空empty(),字符对象的长度size(),某个字符值s[n],连接s1+s2,替换s1=s2,相等s2==s3,不等s3!= s4, 大小比较<,<=,>,>=;
2.处理字符中字符:isalnum(c):是否是字母或数字,isalpha(c):是否是字母,isdigit(c)是否是数字,islower(c)是否是小写,
初识vector
vector用来存储相同类型的数据,又称作容器,vector是一个类模板;模板是不是类,也不是函数,编译可以根据类模板来创建一个类称作实例化一个类,引用类模板是为了减少相似代码的冗余。使用类模板创建对象的时候需要指定存储的类型;
vector<int> nums; vector<vector<string>> file;
注意:vector可以容纳大多数类型的对象作为其元素,引用不是对象,所以不存在包含应用的vector;
定义和初始化:
vector<T> v1; //执行默认初始化 vector<T> v2(v1); vector<T> v2 = v1; vector<T> v3(n ,val); //n 个 val; vector<int> v3(2,12) vector v4(n); vector v5{1,2,3}; // 初始化 1,2,3 ;列表初始化
当使用默认初始化的时候,编译器会根据赋值的类型而初始特定的值,基本内置类型为0,注意,当有些类要求必须提供初始值时,而vector有些类型不支持默认初始化时,这个时候就必须提供初始化元素值;
注意在定义以及初始化的过程中,使用(),即用来定义vector容器的数量,使用两个数字,则是初始化为n个指定的数值,使用{},优先选择则是使用列表进行初始化为某个具体的值,使用两个数字,则是初始化两个具体的值;只有无法执行列表初始化时,才会考虑其他初始化方式。
vector<string> v6{3}; //初始化3个默认初始化的元素;
vector添加元素
因为初始化只能对于少量的元素有用,对于大量的元素,则初始化不合适,因此可以在创建一个小容量的对象,然后向容器中添加元素;
vector<int> nums; //保存int类型; nums.push_back(3);
vector中还有其他操作,例如:empty(),size(),push_back(),v[n],==,!= ,<,<=,>,>=
对于vector访问和字符串的访问差不多,可以下标访问vector中元素,下标从0开始;
注意对于空的容器,不可以使用下标的方式来添加元素,因为空的容器,不存在任何元素,也就不可以使用下标访问元素。
迭代器
提供了对象的间接访问,使用迭代器可以访问某个元素,迭代器也可以从一个元素移动到另一个元素,迭代器的会返回迭代器的成员,begin是成员负责返回指向第一个元素的迭代器,end成员则负责返回指向容器尾的下一个元素。
迭代器中的运算符:
++:下一个元素,
--:上一个元素,
==:相等 ,
!=:不相等,
->:解获取该元素中指定的成员
*:返回迭代器中指向元素的引用;
迭代器的类型
iterator或const_iterator来表示迭代器的类型;
iterator迭代器,可以读写容器中对象;
const_iterator迭代器,只能读去读容器中的内容,不能写;
vector<int> nums; //保存int类型; nums.push_back(3); cout << nums[0] << endl; for (vector<int>::iterator begin = nums.begin; begin != nums.end(); begin++) { cout << (*begin) << endl; }
数组
数组类似与vector,用来存放相同的对象的容器,但是数组的大小是固定的,
数组的定义和初始化
int a[10]; //10个元素,存储int int *p[23]; //23个元素,存储指向int类型的指针;
数组的初始化:
显式初始化数组 int a[2] = {1,2}; 字符数组初始化的化,如果直接使用字符串,则会在后面添加一个字数结束\0 char a[2] = {'a','b'}; chara[] = "hello"
注意:数组名是一个常量,不能禁止拷贝赋值;
int a[2] = {1,2}; int a3[] = a; // 编译错误;
注意数组不可以存放引用=
数组可以存放绝大数类型的对象,可以存放指针的数组,又因为数组也是对象,所以也定义数组的指针即数组的引用,默认情况下,类型修饰符从右向左依次绑定,
int * ptr[10]; //含有10个整形指针的数组; int (*pattry)[10] = &ptr; //定义一个指向含有10个整数的数组; int (&arr)[10] = pattry ; //定义一个引用,含有10个整数的数组 int *(&array)[10] = ptr;
数组的访问可以使用下标,防止数组的下标越界,数组的下标从0开始;
对数组元素使用取地址符就能得到指向该元素的指针,注意数组名的特殊,数组名是一个指向数组首元素的指针,数组名是一个常量;
string names[] = {"lisi", "zhangsan"}; string *p = &names[0]; string *p1 = names;
注意:对于数组的指针,可以使用++,--操作,这样指针会移动到下一个元素的地址,移动的空间的大小为数组存放类型的大小;使用解引用可以获取指针指向的数组的存储的对象;
String函数库有String函数,如:srlen(p)字符长度,strcmp(p1,p2)字符比较,strcat(p1,p2)字符连接;strcpy(s1,s2)字符复制
多维数组:即多个一维数组的组合,可以使用下标访问;
对于多维数组名,也是首元素的地址,可以使用指针指向,并解引用访问,也支持++,--操作;
表达式
表达式是一个或多个运算对象组成,求值可以得到一个结果,子面值和变量是最简单的表达式;表达式不是右值就是左值,左值即可以位于赋值语句的左边,右值即右边,左值可以理解成一个存储空间,用来保存对象;
运算符有:算术运算符+-*/逻辑运算符有:!< > == != 赋值运算符==,条件运算符:?:位运算符:&^!,sizeof运算符,sizeof(),逗号运算符:,
注意:逻辑运算符&&,||的截断,&&运算符只要第一个是false,则不会再计算第二个,||则只要第一个是true,则不会再计算第二个;
类型转换:
当两个对象不是同一个类型的时候,则不会直接进行运算,会将两个类型转换为统一类型然后进行运算,这种叫做隐式转换;条件表达式中,小int类型的会转换为int类型,条件中,非布尔转换为布尔;数组名转换为指针;
算术转换:将算术类型转换为另一种算术类型,整型提升:负责把小整数类型转换为较大的整数类型,
显式转换:隐式转换是小类型的向大类型的转换,如果需要大类型的向小类型的转换,则需要显式的转换,
命名的强制类型转换:cast-name<type>(expression);</type>
cast-name:
static_cast:除非是const,其他的都可以进行转换,将要给较大的算符类型转换为较小的类型;
const_cast:去掉const性质,将一个const常量转换为非const常量;
reinterpret_cat:较低层次的额重新解释,将要给指针强制为别的类型;
旧的强制类型转换:type(express)
**语句:
条件if,else,循环:while,for,异常try-catch语句;跳转goto语句;