引子:
问题:
指针指向变量必须类型一致(int对int*类型指针),这样计算,解引用才能得到正确的结果,那引用也是如此吗?
回答:(常引用)
从语法来说,引用需要与被引用变量类型相同,但是请看下面代码:
如果int&r=d会报错,为什么const修饰一下就行了呢?
从底层来说:类型转换是产生一个常量性临时变量(同const修饰),把被转换数的某一部分给予这个临时变量,再把临时变量给予左值。代码中是把d的整数区给予临时变量,再把常量性临时变量给r引用,这就是为什么直接引用不同类型变量会报错,根本在于不能引用类型转换产生的常量性临时变量。同理,用Int变量接受double型变量也是如此。(此临时变量作用域任然是代码块内)
这同样使得被const修饰的引用能引用所有会类型转换的量(包括常量),因为其本质是引用常量性临时变量。
拓展:
另一个产生常量性临时变量的场景:表达式运算。
可以看到,编译器用两个寄存器分别拷贝了两个变量,把其中一个寄存器的加到另一个上,再把加完的给个临时变量(rbp+64h)在把临时变量地址给寄存器,把临时变量给j引用。
1.相同与不同
1.不同:1.引用在语法上不开辟空间,指针开辟指针变量
(底层两者都开辟空间,引用也是用指针实现的)
2. 定义:引用定义时要初始化,且不能初始化为常数和空,且定义后不能改变引用对象,指针相反。
3. sizeof:引用为所引用对象类型大小,指针为4或8字节。
4.运算:引用为引用对象运算,指针只能+n跳过指向类型的空间。
5.使用:无多级引用,且使用时由编译器处理,比指针安全。
2.相同;
1. 效率:因为引用底层由指针实现,所以指针与引用效率相同。与传值相比他们在作为传参以及返回值类型上效率提升很多。(传值要开辟空间,拷贝值)
注意:引用不能替代指针,因为指针能改,让其在链表等结构中成为必要。