转眼三个星期过去了,也是时候总结一下课程知识了,总的来说目前的内容不难理解。
开学第一周学习了指针,引用,数组,结构体,联合,枚举等,第二周主要是字符串string,动态数组vector以及文件流和字符串流。
c++新增内容:
constexpr对象:,声明为这种类型的对象须为常量,由常量表达式初始化
与const区别:constexpr int a = length();//在编译时计算出length返回值
const int a = length(); //a可在运行时获得,之后不改变。
auto类型说明符:
用auto类型声明变量的类型,由编译器自动分析表达式类型,所以定义auto类型数据必须有初始值!!!ps:不能用变量定义,一定是确定值!
decltype类型指示符:需要一个事先的类型,有两种表达方式:
1. decltype(sizeof(int)) size; //size是int型。
2. int c; decltype(c)size; //size是int型。
decltype与auto可以让我们不需要记一些复杂的变量类型名称。
引用:
左值引用:左值引用又称别名,可以作为对象的另一个名字,通过左值引用可以间接的操控对象。在程序中,引用主要是函数的参数。
引用的类型标识符和一个取地址符(&)来定义。引用必须初始化,初始值是一个有内存的地址。一般在初始化时,引用和将它的初始值对象一直绑定在一起。因为无法让引用重新绑定到另一个对象,所以引用必须初始化。
右值引用:在赋值过程中,出现在赋值号右边的为右值引用
左右值引用区别:可以取地址的,有名字的为左值引用。没取地址,没有名字的为右值引用。
右值引用就是必须绑定到右值的引用。定义形式:
类型 &&右值引用变量=右值表达式; //可以是表达式
指针:
在程序运行的时候,代码以及数据都会存在内存当中,内存是有序的字节序列,而变量都会直接分配一定的内存的字节单元,我们可以通过直接按名字访问,也可以用第二种方法,既通过内存的地址访问所需的内容,这就需要一种新的内存单元,那就是指针。
指针保存着一个对象的地址,或者可以说指向这个对象,其中内存存储的是其指向元素的地址,可以间接调用。
指针变量的定义:
int *pi; //定义一个存放int类型的指针,可以指向int元素。同理,只需要换换类型就好
int* pi; //效果同上;
int* pi,pi2;只有pi是指针,而pi2不是
指针可以间接的改变对象的元素,如:
int x=100;
int *pi=&x;
*pi=10;
这样x=10;间接的操控pi指向的x;
指针一般定义都需要进行初始化,切记不可乱指向,可能会导致程序崩溃,一般的初始为空指针方法:
int *pi=0;
int *pi=nullptr;
int *pi=NULL;
不可以间接通过变量0来让他成为空指针;
可以通过算术运算来进行地址值的增加与改变
如pi++ 如果是int则加四个字节,是char加一个字节。
说到了指针就要说一说迭代器了,迭代器是一种非常类似指针的东西,专门指向容器中的空间,来保证容器内容的取用
迭代器:
迭代器是连接stl(标准模板库)中容器与算法的桥,一些容器如set需要用迭代器才可以指向元素与运用,但vector可以直接直接通过下标的方式进行输出,但不可更改,
定义:
vector<int>::iterator iter;
*iter 解引用,既指向元素,可用于输出,一般先使iter指向容器的初始地址。例如iter=s.begin();
const vector<int>s; 使iter=s.begin();
等同于 vector<int>s; 使iter=s.cbegin();
iter+=n;加法的复合赋值。也可以减法;
iter++;指向容器的下一个元素;
iter+n;指向加到第n个元素,也可以减;
可以通过==或!=进行判断指向元素是否相同;
现在说一下stl中的string与vector:
string:
string表示可变长度的字符序列。可以通过下标的方式如:string s;s[1]则表示第二个字符
string支持字符串之间的复制,比较,连接等操作。
另外,使用string有一个必要的头文件,#include<string>
另外,char字符串的一些基本函数: ps:这些是char类型能用!!! char字符用ctring头文件
strlen(s); 返回s的长度,空字符不会计入
strcmp(s1,s2); 比较s1 s2,如果相等返回0;p1大返回正值,p2大返回负值
strcat(s1,s2); 把s2附加到s1后面
strcpy(s1,s2); 把s2复制到s1之中
string中基本操作:
string s1; 定义
string s1(s2); s2是s1副本
string s1=s2; 等价于上
string s1(n,'a') n个a组成s1
os<<s 把s写到输出流os中,返回os
is>>s 从输出流is读取字符串赋给s;字符串以空白分隔,返回is
getline(is,s); 从输入流is中取一行给s
s.empty(); s空返回true(bool数)非空返回flase
s.size(); s的字节个数
s.c_str(); 转换,返回s中内容对应的c风格字符串首地址
s1+s2 返回s1连接s2的结果
s1+=s2 s1后接s2
vector
和string一样,需要有个头文件为#include<vector>
定义方式:
vector<数据类型>变量名;
如:vector<int>v;
vector<int>v2(v1);v2含有v1的所有元素
vector<int>v(n,val); 包含n个重复元素,内容都是val
vector<int>v(n); v包含n个重复执行值初始化的元素
vector<int>v{a,b,c.....};v包含初始值个数的元素,被赋予相应的初始值
几种基本操作:
v.empty(); 是空返回true,非空返回flase 依然是bool
v.size(); v的元素个数
v.push_back(a); 向尾部添加一个元素a;
v.pop_back(); 删除v的尾端的一个元素
v[n] v的第n个元素
v.at(n); 返回v中第n个位置上元素的引用,下标越界通知异常
这些都是一些比较基础的知识点运用,也是目前我所掌握的,内容的补充需要更深入的研究探讨。
文件流与字符串流:
文件流是一种数据读入与输出的方式,我们最先接触的是从键盘上获得数据并输出到屏幕,而文件流则不同,它是从文件中获取所数据并把处理后的数据放到指定的文件当中,倘若没有这个文件,那么电脑会创造一个文件然后将数据放入其中。
文件流的头文件是fstream,其中的主要操作:
ofstream :文件的输出操作,从内存(文件)中写入存储设备
ifstream :文件的读入操作,主要是从存储设备中读取数据到内存
fstream :读写,对打开的文件进行读写操作
fstream中含有的基本函数:
打开文件 :open();
用于打开文件,使其与文件流中数据关联,只有在使用这个函数之后,才可以用ofstream,ifstream,fstream对文件的读写操作
打开文件中有前缀,不同前缀有不同含义,根据自己的需要选择即可,如:
in 为输入而打开文件
out 为输出而打开文件
ate 初始位置从文件尾开始
app 输出内容附加在文件末尾
trunc 若文件已存在则先删除该文件
binary 二进制方式处理文件
关闭文件: close();
这个函数会将缓存中的数据排放出来并关闭文件。这个函数使用后就可以被其他的进程访问,一个电脑不能执行太多文件,所以close这个文件是很有必要的。
其中输入与输出为
in>>与out<<与cin和cout用法相同,唯一的不同就是针对的对象不同了,这是针对于文件的读写。
stringstream类,
头文件就是stringstream,其作用是将流与存储在内存中的string对象绑定起来,切记是string对象!
几种用法:
str() 将其使用的对象所包含的内容赋给一个string类型数据。
可以用于将string类型转为其他类型,
用法:
stringstream ss;
string s=“3.265959”;
ss<<s;
ss>>x //x是要将转换的数值放入的变量,如要转int类型,那么x就是int型
在计算机中这是一种方便的从文件中得取数据的方式,与键盘输入一样,只是换了种获取数据的渠道。却能处理很多不方便输入的数据,减少了繁琐的输入过程以及制作文件的过程。
函数:
函数:
函数是一个命名的代码块,可以调用这个函数来执行对应的代码,用这些代码实现各种算法,完成特定任务。
函数定义:
函数首先选定一个函数类型,然后定义一个函数名,函数操作值为参数,可以称为形参,结果为返回值,返回值称为返回类型,函数执行
基本定义方式:
返回类型 函数名 (形参){函数体既代码块};
返回类型 有各种数据类型如int double 等,不详细介绍了,其中有一种为void,函数没有参数,bool返回波尔型,分为true,false;
函数调用的方式:
函数名(实参);
注意!!这个地方是实参,不需要加参数的数据类型。
函数值返回:
返回用return语句,如返回a的值,那么就是return a;用于将控制权返回到主函数,如果是return ;那么就是仅仅返回到主函数。
参数传递:
函数的形参是局部对象,仅在函数的作用域中见到,每次调用函数时,会创建参数,然后在使用过后删除,作用原理就是将实参赋值到形参,然后带入代码块中进行运算,返回结果。
如果形参是引用类型,形参将绑定到对应的实参上,否则将把实参的值复制后给形参。
当实参的值复制给形参时,形参和实参是两个独立的对象,实参是按值传递,或传值调用函数。
传引用,按引用传递参数:
形参为引用类型是,对应的实参被称为按值引用,或称为引用调用函数。引用形参绑定到实参,是实参对象的别名。
按值传递:
把实参的值复制到形参的存储区中,既把实参值初始化为形参。
参数传递特殊要求:
数组和函数做参数要用指针。
拷贝构造函数的参数必须传引用。
数组要求:数组长度与参数声明无关,如果在函数内部要使用数组的长度,应该将它作为单独的一个参数。
返回后:函数执行结束后,函数占用的栈存储空间被释放,原本位于这段存储空间的局部对象和临时对象都被释放,返回的局部对象引用或指针将指向无效内存区域
函数重载:
同一种函数名,但形参列表不同,就为重载函数,减少记忆量,举个例子:、
int f (int ,int);
与 double f(double , double);
仅仅名字相同,但使用时可以根据实参的性质而使用相对应的函数。