①auto与decltype
auto 指定符(C++11 起):
对于变量,指定其类型将从其初始化器自动推导而出。
对于函数,指定其返回类型是尾随的返回类型或将从其 return 语句推导出 。
对于非类型模板形参,指定其类型将从参数推导出。
decltype 指定符:
检查实体的声明类型或表达式的类型及值分类。
具体区别:
auto 通过变量的初始值来推断变量的类型 auto会忽略掉顶层const, 保留底层const.
decltype 用于从表达式的类型推断出要定义的变量的类型 不论是顶层const还是底层const, decltype都会保留
②new与delete
new和delete运算符是用于动态分配和撤销内存的运算符。
一、new用法
1.开辟单变量地址空间
使用new运算符时必须已知数据类型,new运算符会向系统堆区申请足够的存储空间,如果申请成功,就返回该内存块的首地址,如果申请不成功,则返回零值。
new运算符返回的是一个指向所分配类型变量(对象)的指针。对所创建的变量或对象,都是通过该指针来间接操作的,而动态创建的对象本身没有标识符名。
一般使用格式:
格式1:指针变量名=new 类型标识符;
格式2:指针变量名=new 类型标识符(初始值);
格式3:指针变量名=new 类型标识符 [内存单元个数
2.开辟数组空间
指针变量名=new 类型名[下标表达式]
一般用法: new 类型 (初值)
二、delete用法
-
删除单变量地址空间
int *a = new int; delete a; //释放单个int的空间
-
删除数组空间
int *a = new int[5]; delete []a; //释放int数组空间
③函数
首先介绍一下函数中传值与传址的概念:
传值:传值无非就是实参拷贝传递给形参,单向传递(实参->形参),赋值完毕后实参就和形参没有任何联系,对形参的修改就不会影响到实参。
传地址:为什么说传地址也是一种传值呢?因为传地址是把实参地址的拷贝传递给形参。还是一句话,传地址就是把实参的地址复制给形参。复制完毕后实参的地址和形参的地址没有任何联系,对实参形参地址的修改不会影响到实参, 但是对形参地址所指向对象的修改却直接反应在实参中,因为形参指向的对象就是形参的对象。
传引用:传引用本质没有任何实参的拷贝,一句话,就是让另外一个变量也执行该实参。就是两个变量指向同一个对象。这是对形参的修改,必然反映到实参上。
④左右值引用
C++的表达式要不然是右值,要不然就是左值。这两个名词是从C语言继承过来的,原本是为了帮助记忆:左值可以位于赋值语句的左侧,右值则不能。
在C++语言中,二者的区别就没那么简单了。一个左值表达式的求值结果是一个对象或者一个函数,然而以常量对象为代表的某些左值实际上不能作为赋值语句的左侧运算对象。此外,虽然某些表达式的求值结果是对象,但它们是右值而非左值。可以做一个简单的归纳:当一个对象被用作右值的时候,用的是对象的值(内容);当对象被用作左值的时候,用的是对象的身份(在内存中的位置)。左值与右值的根本区别在于是否允许取地址&运算符获得对应的内存地址。
⑤标准库类型string
1 定义和初始化string对象(包括直接初始化和拷贝初始化)
如果使用=号初始化一个变量,实际上执行的是拷贝初始化,编译器把等号右侧的初始值拷贝到新创建的对象中去,而如果不使用等号,则执行的是直接初始化
string s1=“hello,world”; //拷贝初始化
string s2(“hello,wolrd”); //直接初始化
string s3(10,‘c’); //直接初始化
2 string对象的基本操作
输入 输出
string s1;
cin>>s1;
cout<<s1;
//cin输入时string类型对象遇会自动忽略开头的空白(即空格符,制表符,换行符等)并从第一个真正的字符开始读起,直到遇到下一处空白为止,比如输入一个 hello world 输出只是一个hello
getline有时我们希望保存输入中的空白符用getline
s1.empty() s1返回为空为true,否则返回为false
s1.size() 返回s中字符的个数
s[n]返回s中第n个字符的引用,n从0开始
s1+s2 返回s1和s2连接后的结果
s1=s2 用s2的副本代替s1
s1==s2 s1!=s2 还有>= <= < > 都对大小写敏感
输入一行的字符并计算非空行输入字符的个数
#include
#include
using namespace std;
int main()
{
string s;
while (getline(cin, s))
{
if (!s.empty())
{
cout << s << endl;
cout << “字符数为:” << s.size() << endl;
}
}
}
六:vector类型
C++内置的数组支持容器的机制,但是它不支持容器抽象的语义。要解决此问题我们自己实现这样的类。在标准C++中,用容器向量vector实现。
vector是C++标准模板库中的部分内容,它是一个多功能的,能够操作多种数据结构和算法的模板类和函数库。vector之所以被认为是一个容器,是因为它能够像容器一样存放各种类型的对象,但是一个容器中的对象必须是同一种类型。简单地说,vector是一个能够存放任意类型的动态数组,能够增加和压缩数据。
vector是一个类模板,不是一种数据类型。可用来定义任意多种数据类型。vector类型的每一种都指定了其保存元素的类型。因此vector 等都是数据类型。
⑦迭代器
迭代,顾名思义就是重复做一些事很多次(就现在循环中做的那样)。迭代器是实现了__next__()方法的对象(这个方法在调用时不需要任何参数),它是访问可迭代序列的一种方式,通常其从序列的第一个元素开始访问,直到所有的元素都被访问才结束。 [注意]:迭代器只能前进不能后退
迭代器的优点:
使用迭代器不要求事先准备好整个迭代过程中的所有元素。迭代器仅仅在迭代到某个元素时才计算该元素,而在这之前或之后元素可以不存在或者被销毁。因此迭代器适合遍历一些数量巨大甚至无限的序列。
八:struct结构体
首先,结构体也是一种数据类型,和int,char等一样;但它更像一个集合,结构体当中还包括很多成员,这些成员可以是相同的数据类型,也可以是不同的数据类型;
因为结构体是一种数据类型,所以可以定义数据体变量,变量当然也可以初始化,还可以被引用;
数据体变量只能放一组数据,要放多组数据可以用结构体数组,可以按照数组的方式来理解,只不过一个元素当中不再是单个数据,而是多个数据,每一个元素都是结构体类型
还有结构体指针,顾名思义,就是指向结构体变量其实地址的指针;
另外,结构体类型只是结构形式,只有定义结构体变量时,才会被分配内存。
⑨:文件输入输出流
a.输入输出重定向
c:>program < inputfile >outputfile
运行名为program.exe的可执行程序,用文件inputfile作为输入,用文件outputfile作为输出。
十:重载函数
重载函数是函数的一种特殊情况,为方便使用,C++允许在同一范围中声明几个功能类似的同名函数,但是这些同名函数的形式参数(指参数的个数、类型或者顺序)必须不同,也就是说用同一个运算符完成不同的运算功能。这就是重载函数。重载函数常用来实现功能类似而所处理的数据类型不同的问题。但是重载函数的返回值类型可以不同。