<iostream>
是input output stream的缩写,是标准的输入输出流库,定义了标准的输入输出对象。
std::cin:
是istream类的对象,主要面向窄字符的标准输入流,流提取操作符。以字符串的方式读取输入的数据然后再进行相应的转换,所以不需要指明类型。
std::cout:
是ostream类的对象,主要面向窄字符的标注输出。对于cout中c的含义:将后面要输出的类型转成字符串,所以不需要指明类型
std::endl:
end line的缩写,是一个函数,流插入输出时,相当于插入一个换行字符加刷新缓冲区。
cin,cout,endl都属于c++标注库,c++标准库都放在一个叫做std的命名空间中,所以想要使用必须通过相应的命名空间,或者将std展开:using namespace std;或者using std::cout; using std::cin
<<是流插入操作符,>>是流提取操作符(在c语言中这两个是左移右移操作符)支持连续的流插入和流提取
在使用std::cout<<"hello word";可以自动识别类型,换成字符串进行输出。
缺省参数
:在函数定义时直接给形参赋值,在使用函数时如果传了参数就不适用赋的值,如果没有传参就使用缺省的值。
如果函数的声明跟定义是分离的,那么缺省值只能在声明的时候给,不能在定义的时候给。
注意:对于函数参数的传递必须是从左到右传,应该是连续的,就是不能跳跃着传参数,不能出现两个传的参数中间空一个空。
全缺省
:就是没有一个参数的传递
半缺省
:注意对于缺省参数的缺省是右边开始的,也是连续的,从开始有默认缺省参数后面都需要有缺省参数,左面的可以一直连续没有缺省的参数。
缺省的参数就像是一个备胎,在主角不在的时候才会勉强使用。
函数重载
:c++支持在同一作用域中出现同名的函数(这里的同名就只是名字的相同)。这里的同名函数的名字已经相同了,所以函数的参数或返回值一定要有所区别,可以是返回值类型不同,参数类型不同,参数个数不同等等。
引用
:类型名+&;引用就是给已经存在的变量取一个别名,就是名字不一样罢了,都是指向同一个东西。引用是没有开辟新的空间的,还是原来的的那个空间,只不过多了个名字。
typedef是对类型的取名字。
当我们在函数传参时如果形参时有一个别名的话,以前的传参时传值的传参,形参其实是实参的一份临时拷贝。但是当我们使用别名时,其实形参就不是实参的临时拷贝了,形参就是实参(这里说是形参也不够准确,应该叫别名)当我们改变别名时,真名也是被改变的。这点跟形参有显著区别。
引用的特性
1.引用在定义时必须初始化
2.一个变量可以有多个引用
3.引用一旦引用了一个实体,就不能再引用其他实体。
对于引用的使用:
1.引用在实践中主要是用于引用传参和引用做返回值中减少拷贝提高效率和改变引用对象的同时改变被引用对象
2.引用传参跟指针传参的功能是类似的,引用传参更加方便一些。
3.c++的引用定义后不能改变方向
4.对于函数的引用返回值可以通过改变这个函数的返回值来改变被引用的对象。注意并不是任何情况都能用引用返回,比如说在函数中定义的变量再用引用返回是不行的,当这个函数返回的时候就没有这个变量的空间了。
const引用与权限问题
在引用中:
当一个变量被const修饰时,他的引用在定义时也要被const修饰,权限不能放大:const对象必须用const引用。但是权限可以被缩小:当一个变量没有被const修饰,但是其引用是可以被const修饰的,也就是权限被缩小了,但是这里的被引用对象还是可以被修改的,而别名就无法被修改了。这里就要考虑const的性质了:就是const修饰的是一个变量的名字,并不是那一份空间,只停留在名字层面上,所以对于不同修饰的不同的名字的同一个空间其权限可能不同。
在指针中:
对于指针来说,权限也是同样存在的。看以下代码:
int a=1;
const int* pa=&a;//注意这里const int修饰的是pa指针指向的空间的内容,而不是指针本身。
int* p=pa;//这是错误的,因为对于pa指针的指向内容是无法修改的,这里权限被放大了,但是同样的权限可以被缩小。
再看一组代码:
int a=1;
int* const pa=&a;//注意这里的const修饰的是pa指针本身。
int* p=pa;//这里是pa拷贝到p中,改变p并没有改变pa,没有问题。
临时对象
:所谓临时对象就是编译器需要一个空间暂存表达式的求值结果时临时创建的一个未命名的对象,并且c++规定了临时对象具有常性。
代码:
int a=1;
int& ra=a*3;//这里是错误的,因为a*3是保存在一个常性的临时对象中的,这里相当于权限放大了,前面加const就好了。
double b=1.1;
int& rb=b;//错误,因为在隐式类型转换时会产生临时对象存储中间值。这里也是一个权限的放大。前面加const就好了。
所以const修饰的引用是很宽泛的:
1.可以引用const对象
2.普通对象
3.临时对象
引用跟指针的关系
1.语法概念上,引用是一个变量取别名不开空间,指针式用来存储一个变量的地址要开空间。
2.引用在定义时必须初始化,指针在定义时建议初始化,但不是必须。
3.引用可以直接访问指向的对象,而指针需要解引用。
4.sizeof中的含义不同,引用结果为引用的类型大小,而指针这取决于平台是32还是64。
5.引用在初始化时引用了一个对象,就不能再引用其他的对象,但是指针可以不断地改变指向的对象。
6.引用一般问题出现的比指针少,指针会出现空指针和野指针的情况。
7.在汇编层面引用是通过指针实现的。
inline
:inline是为了代替c语言中宏函数,因为宏函数是很容易出错的。
例如一个add的宏:#define add(a,b) ((a)+(b))
但是为什么还用宏呢?因为宏的替换机制不需要像函数一样建立函数栈帧,提高效率。
所以inline出现了
inline:用inline修饰的函数叫做内联函数,编译时c++编译器会在调用的地方展开内联函数,这样调用内联函数就不用建立函数栈帧了,提高了效率。inline对于编译器来说只是一个建议,加上inline编译器也可以选择在调用的地方不展开,不同的编译器关于inline的展开情况不相同,c++标准并没有规定这个。inline适用于频繁调用短小的函数,对于递归函数或者代码较多的函数,加上inline会被编译器忽视。注意在debug版本下的内联函数是不会被展开的,因为要方便调试。
inline声明和定义建议不要分到两个文件中,因为inline被展开就没有函数的地址了,链接时会出错。
nullptr
nullptr是一个特殊的关键字,是一种特殊类型的字面量,可以转换成任意其它类型的指针类型。使用nullptr定义空指针可以避免类型转换的问题,因为nullptr只能被隐式的转换成指针类型,而不能被转换成其他的类型。
其实NULL是一个宏,在传统的c头文件中c++中的NULL可能被定义为字面常量0,而在c语言中被定义为无类型的指针((void*)0)的常量。