引用和指针的区别?
引用必须初始化,指针可以不初始化
定义一个指针和引用汇编指令上一样的,引用底层还是指针
引用只有一级引用,没有多级引用,而指针可以有多级指针
定义一个引用变量和指针变量,它们汇编指令同;通过引用修改所引用内存的值,和通过指针解引用修改指针指向的内存的值,其底层指令同。
查看如下例子:
int main()
{
int a = 10;
int *p = &a;
int &b = a;
*p = 20;
b = 30;
return 0;
}
gcc下看汇编步骤
gcc -c main.cpp -g
objdump -S main.o
如上图可看出指针和引用对应操作在汇编上如出一辙
int a = 10;
int *b = &a;
int &c = a; // 和定义指针变量相比右边去掉&,左边指针替换为&
定义一个数组的引用方法:
int main()
{
int array[5] = {};
int *p = array;
// 定义一个引用变量引用array数组
//int (*p)[5] = &array; // 定义指向数组的指针
int (&q)[5] = array;
cout << sizeof(array) << endl; // 20
cout << sizeof(p) << endl; // 8
cout << sizeof(q) << endl; // 20
return 0;
}
左值引用和右值引用
左值,即有内存有名字,值可以修改
右值引用如 int &&c = 20;
专门用来引用右值类型
指令上,就是自动产生临时量,然后直接引用临时量 ,或者使用常引用也可以绑定右值:
// int temp = 20;
// temp->b
const int &b = 20;
一个右值引用本质上是一个左值,因为其有名字
int main()
{
int &&c = 20;
c = 30;
int &e = c; // 右值右值引用本身是左值
int &&e = c; // error
return 0;
}
不能用一个右值引用变量绑定一个左值
例题
做题时把引用还原为指针,便于理解
写一句代码在内存的0x0018ff44处写一个4字节的10
int *&&p = (int*)0x0018ff44;
int *const &p = (int*)0x0018ff44;
判断对错
// 例1
int a = 10;
int *p = &a;
const int *&q = p; // 等价于const int** <= int**,error
// 例2
int a = 10;
int *const p = &a;
int *&q = p; // 等价于int **q = &p; 即 int** <= int* const *-> int* <= const int *,error