#include
using namespace std;
#include
#include
#include
//第四章知识梳理
//一.引用和指针
/int main() {
int counter = 0;
int& ref1 = counter;
int& ref2 = ref1;
ref1 = 1;
cout << ref2 << counter;
return 0;
}///这里可以多个引用绑定到一个值上面去
//int &refcnt = counter;//1.这里必须注意定义引用时必须和一个对象连在一起
//单个的引用是不行的 int &refcnt;是不行的
//2.引用的对象必须是非const左值 int &ref=i+1;
//3.引用和指针的书写建议按照上述步骤进行
//4.const int ci=0;const int &cnt=ci如此为引用const对象
//当引用const对象时,可用左值或者右值来初始化,也可以用不同类型的值来初始化
//5.auto类型,想要推出一个整型引用,必须显式指出引用类型auto &r=i
//5.const int counter=2;auto &ref=counter;auto虽然会忽略一般的const类型,但对于&会保留下来
//6.decltype和引用(根据其括号里的表达式来推导对象类型)可推导出引用
//7.如果把对象加上圆括号,那么decltype将自动推导出引用类型 int i=0;decltype((i))r1=r2;
//8.右值引用&& 如int i=0;int &&r1=i+1;将左值显式转化为右值的方法:
//std::move(rr1);int &&rr3=std::move(rr1)
//auto &&rr1=i;auto &&rr2=i+1;通用引用
//9.指针 int i=100;int *p=&i
//10.定义空指针:int *ptr1=nullptr;
//改变指向:int *p=&i;int *ptr=&j;p=ptr等价于p=&j;
//11.const和指针
//指针常量 const int p=&j,不能再修改P了;若是让P指向另外一个非const常量也不能对这个左值进行修改
//常量指针(等价于指针)int *const cptr=&i;cptr只能指向对象i
//指向常量的常量指针 const int *const cptrc =&ci;
//12.类型推导和指针
//首先是auto,若表达式的值是地址,auto自动推导出指针类型,(const int *也可以推出)
//也就是说用auto推出指针:auto *p=&i;auto p=&i
//decltype
//13.void指针:其实就是替换了int *ptr中的指针.但不能void指针随意赋给一个指针,必须确保指向同一个类型对象以及需要类型转化
//强制类型转换 如 int ptr=&x;void *ptrd=&x;ptr=static_cast<double *>(ptr)
//14.多级指针
//二级指针:int *ptr=&i;int **pptr=&ptr;int **pptr=&pptr
//总结引用和指针的区别
//定义引用时必须初始化,指针不用
//不存在空引用;但存在空指针;引用实际上就是地址不能改变的指针
//比如说const指针(常量指针)
//二:数组(array)
//1.数组存放在一段连续的内存空间中
//数组的初始化:int arr[5]={};
/int main() {
int arr1[5] = {};这个可以隐式初始化
int arr2[5];这个不能隐式初始化
cout << arr1[0] << arr1[1] << endl;
}/
//2字符数组的初始化
/int main() {
char a = ‘a’;
cout << (int)a;
int i = a;
cout << i;
return 0;将字符对应的ascii码输出,不能直接cout<<a不然的话就直接输出的是a了
}/
//char name[]="lisha"等价于char name[]={‘l’,‘i’,‘s’,‘h’,‘a’,’\0’};
//复杂数组的定义如指针数组和数组指针
/ int arr[5];
int *arrp[5];
int(*parr)[5]=&arr;
int(&rarr)[5]=arr;
*/
/*int main() {
int arr[5] = { 1,2,3,4,5 };
int(rarr)[5] = &arr;
cout <<(rarr+1);输出为2
int (&rarr)[5]=arr;
cout<<rarr;输出为数组
}/
//指向指针数组的指针和引用(有点迷)
//访问数组元素(范围for语句)
//for(declation:expression)如int arr[5]={1,2,3,4,5};for(auto i:arr){cout<<i<<endl}
//如果想对i进行写操作需要int arr[]={1,2,3,4,5};for(auto &i:arr){i=0}引用
//多维数组 int a2d[3][5]={
// { },
// { },
// { }};可读性较强
//访问多维数组元素(嵌套for语句和范围for语句)
//嵌套for语句
/*for(int i=0;i<=n;i++){
for(int j=0;j<=n;j++){
arr[i][j];
}}
/
//范围for语句:
/
for(auto&row:a2d){
for(auto colo:row)
*/
//指针和数组
//当用auto进行类型推导时:auto pa=arr;把arr默认为地址,推导出的是指针类型
//二维数组的指针:int a2d[3][5];int (*p2d)[5]=a2d;
//一个数组可以理解为一个const指针,但两者并不完全等价。
//如大小不同 int arr[3][5];int (*parr)[5]=arr;
/*int main() {
int arr[3][5] = { 0 };
int(parr)[5] = arr;
cout << sizeof(arr) << endl << sizeof(parr); 60; 4;
return 0;
}/
//利用指针访问数组:
//访问一维数组 int arr={1,2,3,4};int *p=arr;;
//指针支持所有的关系运算符,返回两侧指针指向的数组中指向元素的前后位置关系p[4]>p[3];
//指针相减:返回位置距离
/int main() {
int arr[5] = { 0 };
int a2d[3][5] = { 0 };
if (arr[4] > arr[3]) { cout << “arr[4]在arr[3]的前面” << endl; }
cout << (a2d[2][4] - a2d[0][0]);
return 0;
}///错误理解了,不是数组支持关系运算,而是指针支持关系运算
/*int main() {
int arr[5] = { 1,2,3,4,5 };
int *p = arr;
cout << p[0]<<endl;
int a2d[3][5] = { {3},{4},{5} };
int(*parr)[5] = a2d;
cout << parr[0][0]<<endl;一下五种形式等价
cout << *(*parr + 0)<<endl;
cout << *(parr[0] + 0)<<endl;
cout << *(*a2d + 0)<<endl;
cout << (a2d[0] + 0) << endl;
return 0;
}/
//利用auto简化代码书写
/*int main() {
int a2d[3][5] = { {3},{4},{5} };
for (auto p = a2d; p < a2d + 3; ++p) {
for (auto q = *p; q < *p + 5; q++) {
cout << q << " ";
}
}
cout << endl;
for (auto i = &a2d[0][0]; i < a2d[0] + 15; ++i) {//i为int类型
cout << i;
if ((i - a2d[0]+1) % 5 == 0) {
cout << endl;
}
}
return 0;
}/
//string 类型
//1.想要使用任何一个标准和提供的名字,如命名空间属于std有三种方法:
//std::cin;using std::cin;using namespace std;
//string 类型的初始化:复制初始化:string str2="rosita"直接初始化:string str4(“rosita”),
//string str5(5,‘r’)
//string类型的常用操作:输入,输出,比较,相加
//string s;cin>>s和getline(cin,s);一个遇到空白字符停止,一个遇到回车方才停止
/int main() {
string s;
getline(cin, s);
cout << s.size();
}/
//调用一个类的成员函数,在对象名字后面加上.操作符,如果对象是指针。则用->
//string类型的关系运算:比较字母表的顺序,靠后的大,顺序一样,比较长度
//string类型的加法运算:
/int main() {
string s1="hellow ";
string s2 = “world”;
string s3 = s1 + s2;
string s4=“hellow”+“s2”
cout << s3;
}/
//string类型支持下标运算符合也可s.at(),s.front(),s.back();
/int main() {
string s = “hellow”;
cout << s[0]<<endl;
s[0] = ‘H’;
cout << s[0]<<endl;
cout << s.at(0) << endl;
cout << s.front() << endl << s.back();
return 0;
}/
//C风格字符串
/int main() {
char small[] = “c++”;
cout << strlen(small);//不包含结束符’\0’
char big[] = "programming ";
cout << strcmp(small,big);和C++中string比较规则一样
return 0;
}/
//strcat和strcpy使用时会出现一些生成问题
//通常情况下,指针可以很方便的访问数组
//char small[]=“big”;char *p=small;或者可以直接 char *p=“big”;
//vector类型可对容量的大小进行动态的调整;
//使用时候必须包含头文件#include
/int main() {
vectorv1;
vectorv2 = { 1,2,3 };
vectorv3(10);
vectorv4(10, 1);
vectorv5 = { “hellow”,“lisha”,“yan” };
vector<vector>v6(10, v2);
return 0;
}/
//vector添加和删除元素:如添加数组元素;
/*int main() {
vectorvi;
for (int i = 0; i < 2; ++i) {
vi.push_back(i);
}
cout << vi.at(0)<<vi.at(1);
vi.pop_back();
cout << vi.at(0);
int a[3] = { 1,2,3 };
for (int i = 0; i < 3; i++) {
vi.push_back(a[i]);
}
cout << vi.at(3);
return 0;
}*/
//使用迭代器auto itb=vi.begin();其中自动推导的itb类型为vector::iterator
//迭代器的用法相当于指针如利用代码遍历
//for(auto it=vi.begin();it!=vi.end();++it)
//如果迭代器指向的元素类型是类类型,可以用.和->运算符进行成员函数选择
//string str=“hellow” (*it).size()
//it->size()与上面等价
/*int main() {
string str = “hellow”;
string ptr = &str;
cout << str.size()<<endl;
cout << ptr->size() << endl;
return 0;
}/
//枚举类型:限定作用域的枚举类型,不限定作用域的枚举类型
//不限定作用域的:enum color{red,yellow,bule};限定作用域的:enum class stoplight{red,yellow,bule}
//当使用不限定作用域会出现重名的情况,当使用限定作用域则不会;
//枚举类型的初始化:
//color b=red//正确;stoplight b=red//错误;stoplight b=stoplight::red;//正确
//每个枚举类型都有一个默认的常量整数值,从0开始一直加1;当然指定一个枚举类型,后面的跟着加一就行
//强制类型转化将一个整型值转化为一个枚举类型
//color c2=static_cast(1)