左值引用和右值引用

目录

辨析引用和指针

代码段

定义引用变量的技巧

同一内存

指针和引用的简单运用

辨析两类指针

数组、指针、引用

辨析左值引用和右值引用

代码段

左值引用和右值引用


辨析引用和指针

1、引用是一种更安全的指针

说明:引用必须初始化,而指针可能是野指针

2、引用必须初始化,指针可以不初始化

3、引用只有一级引用,没有多级引用;指针有一级指针,也有多级指针

4、定义一个引用变量和定义一个指针变量的汇编指令是相同的

通过引用修改内存值和通过指针解引用修改内存值的底层指令也是相同的

代码段

定义引用变量的技巧

// 定义引用变量的技巧

// 首先,定义一个指针变量
int a = 1;
int * p = &a;
// 然后,将&符号移动到*符号的位置,覆盖*符号
int a = 1;
int & p = a;
// int * p = &a;  =>  int & p = a;
// 按照这种方式,最终p是一个引用变量

同一内存

// 同一内存

#include
using namespace std;

int main()
{
	int a = 1;
	int * p = &a;
	int & b = a;
    // a、*p、b属于同一内存

	*p = 2;
	cout << a << " " << *p << " " << b << endl;
	b = 3;
	cout << a << " " << *p << " " << b << endl;
    cout << "总结:a、*p、b属于同一内存" << endl;

	return 0;
}

/*
2 2 2
3 3 3
总结:a、*p、b属于同一内存
*/

指针和引用的简单运用

// 指针和引用的简单运用

#include
using namespace std;

void swap1(int * a, int * b)
{
    int t = *a;
    *a = *b;
    *b = t;
}

void swap2(int & a, int & b)
{
    int t = a;
    a = b;
    b = t;
}

int main()
{
    int x = 1;
    int y = 2;

    cout << "使用swap1()之前:x的值为" << x << ",y的值为" << y << endl;
    swap1(&x, &y);
    cout << "使用swap1()之后:x的值为" << x << ",y的值为" << y << endl;
    swap2(x, y);
    cout << "再使用swap2()之后:x的值为" << x << ",y的值为" << y << endl;

    return 0;
}

/*
使用swap1()之前:x的值为1,y的值为2
使用swap1()之后:x的值为2,y的值为1
再使用swap2()之后:x的值为1,y的值为2
*/

辨析两类指针

// 辨析两类指针

#include
using namespace std;

int main()
{
    int array[5] = { };

    int * p = array;
    int (* q)[5] = &array;

    return 0;
}

/*

指针p
指针p初始化为指向数组array的第一个元素的地址,即array[0]的地址
指针p存储了array的起始地址

指针q
指针q初始化为指向整个数组array的地址(使用括号来明确类型)
指针q存储了整个数组array的地址

两者的区别
p是一个指向单个int元素的指针,而q是一个指向整个int[5]数组的指针
p可以逐个访问数组元素。例如,p++将指向array的下一个元素
q作为指向整个数组的指针,可以用于传递和处理整个数组,也可以通过解引用来访问整个数组

*/

数组、指针、引用

// 数组、指针、引用

#include
using namespace std;

int main()
{
	int array[5] = { };
	int * p = array;

	cout << sizeof array << endl; // 20
	cout << sizeof p << endl;     // 8

    int (& q)[5] = array;
	// 定义引用变量q来引用array数组,q相当于array的别名
	// int (* q)[5] = &array;  =>  int (& q)[5] = array;

	cout << sizeof q << endl; // 20

	return 0;
}

/*
20
8
20
*/

/*
关于输出结果的说明

1、sizeof运算符用于获取对象或类型的大小(以字节为单位)
2、对于sizeof array,数组 array 的大小取决于数组中的元素数量和元素类型的大小
在本例中,array是一个具有5个int元素的数组
每个int类型的大小通常是4字节(具体的大小可能因编译器和平台而异)
因此,sizeof array返回20
3、对于sizeof p,指针p的大小通常是机器字长相关的
即在64位系统中,指针大小为8字节;
在32位系统中,指针大小为4字节
4、q相当于array的别名
因此,sizeof q等于sizeof array,同为20
*/

辨析左值引用和右值引用

左值:有内存,有名字,值可变

右值:没内存,没名字,值不变

左值引用

允许使用替代名称来访问同一对象

右值引用

C++11提供的右值引用专门用于引用右值

注意!右值引用变量本身是左值

代码段

左值引用和右值引用

// 左值引用和右值引用

#include
using namespace std;

int main()
{
    int a = 1;
    int & r1 = a; // 左值引用r1

    int && r2 = 9; // 右值引用r2
    // 以后还可以给r2赋值,例如:
    r2 = 2;
    // 关于int && r2 = 9;
    // 首先,产生一个值为9的临时量
    // 然后,将临时量的地址记录到r2的内存中

    // int & r3 = 3;    // 错误!
    const int & r3 = 3; // 正确!
    // 以后不能给r3赋值
    // 关于const int & r3 = 3; 
    // 首先,产生一个值为3的临时量
    // 然后,将临时量的地址记录到r3的内存中
    // 这些步骤和右值引用步骤相同

    int & r4 = r2;
    // 注意!右值引用变量本身是左值
    // 不能用右值引用变量来引用左值
    // 所以需要使用 左值引用变量 来引用 右值引用变量

    return 0;
}

你可能感兴趣的:(C++,c++,引用)