(参考《程序员面试宝典》)
1.非空区别:在任何情况下都不能使用指向空值的引用。一个引用必须总是指向某些对象。因此如果你使用一个变量并让它指向一个对象,但是该变量在某些时候可能不指向任何对象。这时你就应该声明该变量为指针,因为这样你就可以赋空值的。
相反,如果变量肯定指向一个对象,并且设计不允许变量为空,这时就把变量声明为引用。
这意味着,使用引用的效率比使用指针高。
2.合法性区别:在使用引用之前不需要测试它的合法性。使用指针总是要判空。
3.可修改区别:指针可以被重新赋值;引用则总指向初始化时被指定的对象,以后不许修改,但是指定的对象的内容可以改变。
4.应用区别:使用指针:存在不指向任何对象的可能,可以设指针为空;需要改变指向,在不同的事件指向不同的对象。
使用引用:总指向一个对象并且一旦指向,就不回改变。
(参考1传引用的好处:简单粗暴,适合面试回答:https://blog.youkuaiyun.com/a15994269853/article/details/23995383)
c语言中所有传递给函数的参数都是传值方式进行的。
传值,是把实参的值赋值给行参,那么对行参的修改,不会影响实参的值
传地址,是传值的一种特殊方式,只是他传递的是地址,不是普通的如int,那么传地址以后,实参和行参都指向同一个对象
传引用,真正的以地址的方式传递参数,传递以后,行参和实参都是同一个对象,只是他们名字不同而已, 对行参的修改将影响实参的值。
传递引用与传指针、传值的区别?
(1)传递引用给函数与传递指针的效果是一样的。这时,被调函数的形参就成为原来主调函数中的实参变量或对象的一个别名来使用,所以在被调函数中对形参变量的操作就是对其相应的目标对象(在主调函数中)的操作。
(2)使用引用传递函数的参数,在内存中并没有产生实参的副本(实参传形参是一个初始化的过程,这会产生额外开销),它是直接对实参操作;而使用一般变量传递函数的参数,当发生函数调用时,需要给形参分配存储单元,形参变量是实参变量的副本;如果传递的是对象,还将调用拷贝构造函数。因此,当参数传递的数据较大时,用引用比用一般变量传递参数的效率和所占空间都好。
(3)使用指针作为函数的参数虽然也能达到与使用引用的效果,但是,在被调函数中同样要给形参分配存储单元,且需要重复使用"*指针变量名"的形式进行运算,这很容易产生错误且程序的阅读性较差;另一方面,在主调函数的调用点处,必须用变量的地址作为实参。而引用更容易使用,更清晰。
从本质上来说,传值和传指针都是传值方式,除了传引用之外。
------------------------------------------------------------------
(引用 和 指针 的区别:)
引用的定义
(1)允许在一条语句中定义多个引用,其中每个引用标识符都必须以&开头;
(2)因为无法将引用重新绑定到另外一个对象上,因此引用必须初始化。
(3)因为引用本身不是一一个对象,所以不能定义引用的引用。
(4)一个变量可以有多个引用,而一个引用只能给一个变量对象 。
(5)引用的类型要和与之绑定的对象严格匹配(不严谨)。
(6)引用只能绑定在对象上而不能和字面值或某个表达式计算的过程绑定在一起。
引用与指针
相同点:
底层的实现方式相同, 都是按照指针的方式来实现的:
不同点:
(1)定义上的区别:可以说指针即地址,因为指针是一个存储地址的变量,它指向内存的一个存储单元;引用即别名,引用跟原来的变量实质上是同一个东西,只不过是原变量的一个别名而已。
1 int a=1;int *p=&a;
2 //定义了一个整形变量和一个指针变量p,该指针变量指向a的存储单元,即p的值是a存储单元的地址。
3 int a=1;int &b=a;
4 //定义了一个整形变量a和这个整形a的引用b,事实上a和b是同一个东西,在内存占有同一个存储单元。
(2)指针的值可以为空,但是引用的值不能为NULL,并且引用在定义的时候必须初始化;
(3)引用定义时必须初始化,且在进行初始化后就不会再改变了。 指针可以不用, 正常情况下需初始化为NULL,且指针的值在初始化后可以改变,即指向其它的存储单元;
(4)sizeof求取的值不一样,"sizeof引用"得到的是所指向的变量(对象)的大小,而"sizeof指针"得到的是指针本身的大小;
(5)指针和引用的自增(++)与自减(--)运算意义不一样, 引 用自 加改变变量的内 容, 指针自 加改变了 指针指向;
(6)可以有多级指针, 但是没有多级引 用,(int **p;合法 而 int &&a是不合法的);
(7)指针和引用的地址不同,引用的地址即所引用对象的地址。指针的地址就是它自己的地址,是内存中的一块实实在在的另一块内存;
(8)引用比指针更安全。不会出现像野指针这样的现象。
指针和引用作为函数参数进行传递时的区别
1 #include<iostream>
2 using namespace std;
3
4 void swap(int *a,int *b)
5 {
6 int temp=*a;
7 *a=*b;
8 *b=temp;
9 }
10 int main(void)
11 {
12 int a=10,b=20;
13 swap(&a,&b);
14 cout<<a<<" "<<b<<endl;
15 system("pause");
16 return 0;
17 }
输出结果为:20 10
用指针传递参数,可以实现对实参进行改变的目的,是因为传递过来的是实参的地址,因此使用*a实际上是取存储实参的内存单元里的数据,即是对实参进行改变,因此可以达到目的。