C++学习总结(二)

一.左值与右值

左值一般可以取地址,右值某些情况可以,某些情况不可以。

左值就是可以放在赋值号左边被赋值的值,必须要在内存有实体。

右值放在赋值号右边取出值赋值给其他变量的值。右值可以在内存中也可以在cpu。

右值的引用,省去了去寄存器(寄存器不可取地址)到内存的拷贝,直接在寄存器中进行数据操作,节约了内存,内存优化,

左值通过 std::move(变量名); 转换为右值。

#include<iostream>
#include<stdlib.h>
using namespace std;
void main1()///a b在内存中,a+1在寄存器中
{
	int a = 5;
	int b;
	cout << &a << ' '<<&b<<endl;

	b = a;

	b = a + 1;
	

	system("pause");
}

void main2()//左值引用
{
	int a = 3;
	int & re(a);
	re = 666;
	cout << a << endl;
	system("pause");
}
void change(int &a)//引用地址,建立变量接收实际参数的值
{
	a = 666;
	cout << "change addr=" << &a << endl;
}
void main3()//引用的用途
{
	int a = 6;
	change(a);
	cout <<"main"<< &a <<' '<<a<< endl;
	system("pause");
}
void main4()//引用指针
{
	int num1(5);
	int num2(10);
	int *pnum(&num1);
	int* &rpnum(pnum);
	//rpnum = &num2;//改变指针的指向
	*rpnum = 100;//改变指针指向的值
	cout << *pnum << endl;
	cout << num1 << endl;

	system("pause");

}

void main5()//
{
	int num1(5);
	int num2(10);
	int * &&pnum(&num1);//引用右值
	int* p = pnum;//用于对象拷贝
	p = &num1;//取地址在寄存器
	p = &num2;
	cout << *pnum << endl;//5
	cout << num1 << endl;//5

	system("pause");

}

int &get()
{
	int a = 10;
	int & ra = a;
	return ra;
}
int* &get1()
{
	int* p = new int;//堆上的内存
	cout <<"&p="<< &p << endl;//P是一个野指针
	*p = 10;
	int* &rp = p;
	return rp;

}
void main6()     //指针p在栈上,p的内容在堆上,
                //函数执行后,指针p会消亡,但是堆上的内容会一直保留
{
	int &ra = get();
	cout << ra << endl;
	int* &rp = get1();
	int *p = rp;//指向堆上的地址	

	cout << *rp << endl;//10
	cout <<*p << endl;

	cout << *rp << endl;//指针位于栈上,内存被回收重新利用
	cout << *p << endl;

	delete(p);//删除内存后禁止访问

	cout << "china" << endl;//堆栈重新利用,内存回收

	cout << ra << endl;

	system("pause");
	
}
void main()
{
	int a = 10;
	int &ra = a;//左值引用
	int* &&pa = &a;//右值引用
	cout << &a << endl;
	cout << pa << *pa << &pa << endl;
	system("pause");
}


注:CPP中检测到右值会自动转换为左值

例如:

int num=3;
(num=3)=4;
int num=5;
(num>num1?)num:num1)=2;

   右值转换为左值后赋值

二.C++中的引用

1.引用通过 & 表示引用,注:引用必须进行初始化,例如:

int a=10,b=20;
int &rf=a;
iny &re(b);
2.引用的特点:

1>引用不可以重名

2>建立新的变量名,指向的地址一样,操作相同。(别名,取地址,不允许重定义)

3>引用可以改变指针的指向,同时还可以改变指正指向的值,取地址在寄存器中。

4>改变外部变量的值,作为函数调用的参数表,同时还可以通过传递地址的方式。

void change(int &a)
{
   a=100;
}

void change1(int *p)
{
  p=100;
}
5>左值引用通过指针实现

6>用于对象拷贝

int num=100;
int *&&rpnum=&num;
int *p=rpnum;
#include<iostream>
#include<stdlib.h>
using namespace std;
void main1()//引用一维和二维数组
{
	int a[5] = { 1,2,3,4,5 };
	int b[2][5] = { 0 };
	int (&ra)[5](a);
	int(&rb)[2][5](b);//引用二维数组
	int i = 0;
	for (auto data : ra)
	{   
		data = i + 5;
		cout << data << endl;
	}

	for (int i = 0;i < 2;i++)
	{
		for (int j = 0;j < 5;j++)
		{
			cout << ' ' << rb[i][j];
		}
		cout << endl;
	}
	cout << a << ' ' << ra << endl;
	system("pause");
}
int add(int a, int b)
{
	return a + b;
}
int submit(int a, int b)
{
	return a - b;
}
void change(int (* &rp)(int,int))//通过引用,函数改变函数指针的指向
{
	rp = submit;

}

int (* &changep(int(*&rp)(int, int)))(int,int)//返回值是函数指针的引用
{
	rp = submit;
	return rp;

}
void main2()
{
	int (*p)(int, int)(add);
	cout << p(1, 2) << endl;
	p = submit;
	cout << p(1, 2) << endl;
	int(* &rp)(int,int) = p;//引用一个函数指针
	//rp = submit;//改变函数指针的指向
	rp=changep(rp);
	cout << p(1, 2) << endl;

	system("pause");
}

void main3()
{
	int a = 1, b = 2, c = 3;
	int *p[3] = { &a, &b, &c};
}

struct mystr
{
	char a;
	int b;
	double c; 
	//代码区的函数不计入结构体的sizeof()
	void go()
	{
		cout << "hahahaha" << endl;
	}
};
class myclass
{
	int a;
	int b;
	double c;
};
class myclass1//引用的本质是指针,直接sizeof引用,就是求引用的数据的大小,
	         //引用变量占据四个字节
{
	char & a;
	char &b;
	char &c;
};
void main4()
{   
	int num = 10;
	int &rnum = num;
	double db = 10.9;
	double &rdb(db);
	cout << sizeof(rnum) << endl;//4
	cout << sizeof(rdb) << endl;//8
	cout << sizeof(mystr) << endl;//跳过函数只计算数据16, double类型位于int 和 char 前面时是24
	cout << sizeof(myclass) << endl;
	cout << sizeof(myclass1) << endl;//12
	system("pause");
}

int getdata(int &&num)//右值操作在寄存器中
{
	cout << num << endl;
	num += 10;
	return num;
}

void main5()//右值引用
{
	int a = 5;
	int b = 4;
	cout << getdata(a+1) << endl;//右值的调用
	system("pause");
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值