引用
左值引用 右值引用
void showit(int &&rnum) //右值引用
{
cout << rnum << endl;
}
//左值引用往往引用内存里面值 右值引用往往引用寄存器里面的值
void main09xx()
{
int num = 10;
int& lnun(num); //左值引用 变量别名
int&& rnum(num + 4); //右值引用 快速备份 编译器 自动回收
int a[5]{ 1,2,3,4,5 };
int*p(a);
int* &rp(p); // & 放在类型和变量名之间
rp += 1;
cout << *rp << endl;
int* &&rrp(p + 2); //右值引用 &&
cout << *rrp << endl; //4
int* &&rrrp(&a[1]); //右值引用 &&
cout << *rrrp << endl; //2
showit(a[4] + 5); //10
showit(move(a[4])); //5 move 移动语义 左值变右值
cin.get();
}
引用本质
void main10x()
{
int num = 10;
int data = 20;
int &rnum(num); //引用一旦初始化 不会引用其他变量 引用必须初始化
rnum = data;
double db = 41;
double &rdb(db);
cout << sizeof(rdb) << endl; //8字节 编译器优化处理 引用变量名别名
struct Da
{
double &rdb;
};
cout << sizeof(Da) << endl; // 4字节 引用的本质是指针实现的 简化程序
cin.get();
}
引用指针
void mainxxxxx()
{
int a(4);
int*p(new int(5)); //开辟一块内存 并初始化为5
cout << a << endl;
cout << *p << endl;
int &ra(a); //引用变量
int* &rp(p); //引用指针
ra = 3;
*rp = 12;
cout << a << endl;
cout << *p << endl;
int &&rra(move(a)); //右值引用 有内存实体直接引用 没有开辟内存
int* && rrp(move(p));
cin.get();
}
int & 引用整数 本质指针
int && 引用整数 本质指针 能处理左值(需要move) 右值
int 整数类型
函数参数 返回值引用
参数引用 (以及 指针引用 括号括法)
int num1 = 10;
int num2 = 20;
void change(int* &rp) //C++能用引用 别用指针
{
rp = &num2;
}
int data1 = 100;
int data2 = 200;;
int *xp = &data1;
void change(int** &rpp) //C++能用引用 别用指针
{
*rpp = &data2;
}
void main()
{
int *p(nullptr);
int **pp(&p);
//int** &rpp(pp); //VS2015
//int(** (&rpp))(pp); //VS2013 需要括号说明优先级 先括引用符 再括指针符
// int (***ppp)(nullptr); //VS2013
// int(*** (&rppp))(ppp); //VS2013
int ***ppp(nullptr);
//int*** &rppp(ppp);
int** xpp = &xp;
cout << **xpp << endl;
change(xpp);
cout << **xpp << endl;
cin.get();
}
返回值引用
//返回一个引用
//函数返回值有副本机制
//栈区 自动回收 自动释放 返回值为指针 不能指向栈区 返回值为引用 不能引用栈区
int& getdata()
{
int num = 1; //销毁 在内存
return num;
}
int& getdata1()
{
int*p(new int(5));
return *p;
}
char* & getcode()
{
char*p = "Guoshixian";
return p;
}
void mainx7()
{
//int &rnum = getdata(); //引用原来内存
//int num = getdata(); //拷贝到新的内存
char* &rp = getcode(); //等于引用原生p p在内存 已销毁
char*newrp = rp; //保存rp储存代码区的地址
cout << newrp << endl; //正常打印
cout << rp << endl; //乱码
cin.get();
}
引用数组
数组类别
指针数组: 数组 每一个元素都是指针
数组指针: 指针 指向数组的指针
多维数组名的本质就是一个数组指针
void mainx8()
{
//VS2013 需要阔括号
int a[5]{ 1,2,3,4,5 }; //一位数组
int *pa[5]{a,a+1,a+2,a+3,a+4}; //指针数组
int b[2][3]{ 1,2,3,4,5,6 }; //二维数组
int *pb[2][3]{
&b[0][0] ,&b[0][0] + 1,&b[0][0] + 2,
&b[0][0] + 3,&b[0][0] + 4,&b[0][0] + 5
}; //二维指针数组 每一个元素都是指针
int*p1(new int[5]{ 1,2,3,4,5 }); //堆上一维数组
int**pp = new int*[5]{ p1,p1 + 1,p1 + 2,p1 + 3,p1 + 4 };//堆上指针数组
int(*p2)[4] = new int[3][4]{ {1,2,3,4},{5,6,7,8},{9,10,11,12} }; //堆上二维数组
//pp2是一个指针 指向数组的一行 一行有4个元素
int*(*pp2)[4]{new int*[3][4]};//堆上二维指针数组
//int*(*pp)(nullptr); //初始化VS2013空余一个指针
cin.get();
}
引用一个数组
//vs2015
void mainx9()
{
int a[5]{ 1,2,3,4,5 }; //一位数组
int(&ra)[5](a);
for (auto i : ra)
{
cout << i << endl;
}
int *pa[5]{ a,a + 1,a + 2,a + 3,a + 4 }; //指针数组
int* (&rpa)[5](pa);
for (auto i : rpa)
{
cout << *i << endl;
}
int*p1(new int[5]{ 1,2,3,4,5 }); //堆上一维数组
int* &rp1(p1);
for (size_t i = 0; i < 5; i++)
{
cout << rp1[i] << endl;
}
int**pp = new int*[5]{ p1,p1 + 1,p1 + 2,p1 + 3,p1 + 4 };//堆上指针数组
int** &rpp(pp);
for (size_t i = 0; i < 5; i++)
{
cout << *rpp[i] << endl;
}
cout << "==============================================" << endl;
int b[2][3]{ 1,2,3,4,5,6 }; //二维数组
int(&rb)[2][3](b); //引用二维数组
for (int i = 0; i < 2; i++)
{
for (int j = 0;j < 3;j++)
{
cout << rb[i][j] << " ";
}
cout << endl;
}
int *pb[2][3]{
&b[0][0] ,&b[0][0] + 1,&b[0][0] + 2,
&b[0][0] + 3,&b[0][0] + 4,&b[0][0] + 5
}; //二维指针数组 每一个元素都是指针
int*(&rpb)[2][3](pb); //引用二维指针数组
for (int i = 0; i < 2; i++)
{
for (int j = 0;j < 3;j++)
{
cout << *(rpb[i][j]) << " ";
}
cout << endl;
}
cout << "==============================================" << endl;
int(*p2)[4] = new int[3][4]{ { 1,2,3,4 },{ 5,6,7,8 },{ 9,10,11,12 } }; //堆上二维数组
//指向数组的指针 用{}包含 用大括号初始化二维数组
int(*p3)[4]{new int[3][4]{ { 1,2,3,4 },{ 5,6,7,8 },{ 9,10,11,12 } }}; //堆上二维数组
int(*&rp2)[4](p2); //引用一个行指针
for (int i = 0; i < 3; i++)
{
for (int j = 0;j < 4;j++)
{
cout << rp2[i][j] << " ";
}
cout << endl;
}
cout << "==============================================" << endl;
int*(*pp2)[4]{ new int*[3][4] }; //堆上二维指针数组
int*(*&rpp2)[4](pp2);//引用二维指针数组
cin.get();
}
const与 引用
常量指针 指针常量 指向常量的常量指针
//常量指针: 指向对象不可修改 可改变其指向 声明的对象是一个指向常量的指针(变量)
//const int *p; int const *p;
//指针常量: 指向对象可修改 不可改变其指向 声明的对象是一个常量,且它的内容是一个指针,也就是一个地址。
//int *const b = &a;
//指向常量的指针常量: 是一个常量,且它指向的对象也是一个常量
//const int a = 25;
//const int * const b = &a;
引用于const的关系
void show(const int &rint) //明确只读不写
{
}
void mainx10()
{
int num = 100;
int const &rnum(num); //让别人引用 限定权限
const int &rnum1(num); //等价 一样
int &const rnum2(num); //const 放右边 被忽略
int a[5]{ 1,2,3,4,5 }; //一位数组
const int(&ra)[5](a);
for (auto i : ra)
{
//i+=1; //限定 不能修改
cout << i << endl;
}
cout << "==============================================" << endl;
const int *p(new int(5)); //指向常量
const int *&rp(p); //引用一个指向常量的指针
int *const p1(new int(5)); //指向不可改变 指向的值可以改变
*p1 = 10;
int (*const (&rp1))(p1); //引用一个常量指针
const int *const p2(new int(5));
const int (*const (&rp2))(p2); //引用一个指向常量的 常量指针
cout << "==============================================" << endl;
int *xp(new int(5)); //指向常量
const int *&rxp((const int*&)xp); //强转为常指针
cin.get();
}
引用与函数指针
int gocmd(const char*str)
{
system(str);
return 1;
}
int showcmd(const char*str)
{
cout << str << endl;
return 1;
}
void change(int(*&pfun)(const char*)) //引用作为参数
{
pfun = showcmd; //栈
}
int(* getp() )(const char*) //getp 返回一个函数指针
{
int(*pfun)(const char*)(gocmd);//栈
//int(* &pfun)(const char*)= (int(*&)(const char*)) gocmd; //
return pfun;
}
int(* getitp(int(*&pfun)(const char*)) )(const char*) //getitp 传递一个函数指针引用 返回一个函数指针
{
pfun = showcmd;
return pfun;
}
//参数是一个引用 返回值也是一个引用 ===== 此函数等于输入输出都是操作原生变量
int(* & getitpp(int(*&pfun)(const char*)) )(const char*)
{
pfun = showcmd;
return pfun;
}
void mainx11()
{
//
int(*pfun)(const char*)(gocmd); //定义函数指针并初始化
pfun("calc");
change(pfun);
pfun("sssssssssssssss");
pfun = getp();
pfun("notepad");
getitpp(pfun)("hello "); //等价于 pfun("hello ");
cin.get();
}
引用函数指针数组与函数二级指针
int add(int a,int b)
{
return a + b;
}
int sub(int a, int b)
{
return a - b;
}
int mul(int a, int b)
{
return a * b;
}
int divv(int a, int b)
{
return a / b;
}
void mainx12()
{
int(*pfun[4])(int a, int b) { add, sub, mul, divv }; //函数指针数组 并初始化
//二级函数指针 开辟函数指针数组
int(**ppfun)(int a, int b) { new (int(*[4])(int a, int b)){ add, sub, mul, divv } };
int(*(&rpfun)[4])(int a, int b)(pfun); //引用函数指针数组
int(**(&rppfun))(int a, int b)(ppfun); //引用二级函数指针
for (size_t i = 0; i < 4; i++)
{
cout << rpfun[i](100, 10) << " ";
cout << rppfun[i](100, 10) << " ";
}
cout << endl;
for(int(**ppx)(int,int)=ppfun;ppx<ppfun+4;ppx++)
{
cout << (*ppx)(100, 10) << " ";
}
cout << endl;
cin.get();
}
引用结构体数组
struct info
{
int id;
int num;
//没有返回值 名称和类型一致
info(int nid,int nnum):id(nid),num(nnum) //构造初始化函数
{
}
};
void mainx13()
{
info infos[5]{ {1,1},{1,2},{1,3},{1,4},{1,5} };
info (&rinfos)[5](infos); //引用结构体数组
for (auto i : rinfos)
{
cout << i.id << " " << i.num << endl;
}
info *p( new info[5]{ { 1,1 },{ 1,2 },{ 1,3 },{ 1,4 },{ 1,5 } } );
info*(&rp)(p);
for (int i = 0; i < 5; i++)
{
cout << rp[i].id << " " <<rp[i].num << endl;
}
cin.get();
}
网友评论