我看网上对引用说的大多很宽泛,是一块内存的别名,那它具体是怎么产生的,它本身占据内存吗,怎么保存的,保存在哪儿的
写个简单的小程序来反汇编看看
#include <cstdio>
int main()
{
int a = 2;
int* b = &a;
int& c = a;
return 0;
}
反汇编后(g++ -S *.c)
subq $32, %rsp
movq %fs:40, %rax //将存放初始化局部变量地址给ax
movq %rax, -8(%rbp) //再将这个地址传给基数指针寄存器bp中
xorl %eax, %eax //ax清为0
movl $2, -28(%rbp) //使这个地址存储着常量2
leaq -28(%rbp), %rax //再将a的地址传给ax
movq %rax, -24(%rbp) //将a的地址再存放进bp寄存器中,对应b
leaq -28(%rbp), %rax //再将a的地址传给ax
movq %rax, -16(%rbp) //将a的地址再存放进bp寄存器中,对应c
movl $0, %eax //return 0
movq -8(%rbp), %rdx
xorq %fs:40, %rdx
je .L3
可以看到指针,引用在编译器编译后实现上是一样的,都是取a的地址,再将a的地址存放在bp寄存器中。所以引用其实也是会占据一定的空间的,从编译后来看,它也是一个新的变量,他们的不同是在编译前,在此之前来了解下编译器的符号表
符号表是一种用于语言翻译器(例如编译器和解释器)中的数据结构。在符号表中,程序源代码中的每个标识符都和它的声明或使用信息绑定在一起,比如其数据类型、作用域以及内存地址。这些信息一般以表格形式存储于系统中。如常数表、变量名表、数组名表、过程名表、标号表等等,统称为符号表。
也就是说在操作系统中是各种寄存器堆栈存储变量,编译器中是靠符号表,编译器根据变量是局部还是全局分配内存地址或栈空间,操作时转换成地址数存放在寄存器中了,符号表起到了连接作用
再回到指针与引用,他们的不同就是在符号表中的存储方式不同
程序在编译时分别将指针和引用添加到符号表上,符号表上记录的是变量名及变量所对应地址。指针变量在符号表上对应的地址值为指针变量的地址值,而引用在符号表上对应的地址值为引用对象的地址值。符号表生成后就不会再改,因此指针可以改变其指向的对象(指针变量中的值可以改),而引用对象则不能修改