先写个最简单的测试代码:
test_ref.cpp:
#include<stdio.h>
int main(void)
{
int a = 10;
int &ra = a;
ra =20;
int b = 100;
int *pb = &b;
*pb = 200;
return 0;
}
上面定义了个引用 ra和指针 pb
将上面的代码进行编译:
g++ -S test_ref.cpp
得到以下结果 : test_ref.s
.file "test_ref.cpp"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
.cfi_personality 0x0,__gxx_personality_v0
pushl %ebp
.cfi_def_cfa_offset 8
movl %esp, %ebp
.cfi_offset 5, -8
.cfi_def_cfa_register 5
subl $16, %esp
# int a = 10;
movl $10, -4(%ebp) #这里定义了变量 a, int a = 10
# int &ra = a;
leal -4(%ebp), %eax #对内存 -4(%ebp)取地址,即a存放的地址,放到eax中
movl %eax, -8(%ebp) #将eax中放的a的地址放到-8(%ebp),一个int占4个字节,所以由-4(%ebp)变成-8(%ebp)即是用来存放ra的
# ra = 20;
movl -8(%ebp), %eax #ra=20前戏,将-8(%ebp)存的值,即引用变量ra的值即a的地址值放到eax寄存器中
movl $20, (%eax) #ra=20 ,修改首地址值为eax的值的内存块的值即存放a变量的内存块的值为20,相当于a=20
# int b = 100;
movl $100, -12(%ebp) #定义变量b,int b = 100
# int *pb = &b;
leal -12(%ebp), %eax #对内存-12(%ebp)取地址,即取b的首地址,放到寄存器eax中
movl %eax, -16(%ebp) #将b的首地址放到内存 -16(%ebp)中
# *pb = 200
movl -16(%ebp), %eax # 将pb的值放入 eax寄存器中,即b的地址
movl $200, (%eax) # 修改b的内存块的值为200</span>
# return 0
movl $0, %eax
leave
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3"
.section .note.GNU-stack,"",@progbits
通过上面的例子可以看出 ,引用和指针都是存放变量的首地址的,区别在于,指针的话,要同过 *操作符来访问变量内存的值,即要程序员手动来操作。
指针可通过加减(只能加减)来改变该指针变量中的地址的值。而引用的话不能修改地址值,而是封装了访问变量这一步,即自动解引用,不需要额外的操作符,对引用变量的修改(ra = 200),从上面的例子可以看出,是解析该引用变量里存的地址值访问变量的首地址直接改了该变量的值。而指针是通过*操作符手动解引用。
先讨论到这里,可能写得稍有错误,欢迎大家多多指正。