【面试常见问题】【C++】指针和引用的区别,有哪些不同点,细细道1

首先咱们弄清楚复合类型(Compound type)这个概念,因为指针和引用是Compound type中的两种

引用(reference):

  • 何谓“引用”,这么说吧,相信每个人都有个乳名,后来等到你升学入职啥的发现乳名B格很Low ! 这时候需要为自己起另外一个名字,这就是引用 ! 是一个过程,引用就是为对象另起了一个名字。                                 先明确一下面这两个‘“混蛋”!

变量定义

  • 相信不少C++程序员模糊着“变量(variable)”和“对象(object)”的概念,变量定义的基本形式:类型说明符(type specifier)/基本数据类型( base type)+ 变量名/声明符( declarator),比如
  • int sum = 0, value, units_sold = 0; 

最后谈一下“何为对象”:

对象是什么? 数据,错!  变量的值,还是错! 变量的地址, 好像接近了一点!  准确的讲,对象是内存空间,也就是首地址到截止地址那一段!

C++就是这样,繁琐,木的办法啊。。。继续讲下去:引用是这么运作的,我的乳名叫“唐僧”,引用后呢,“&唐宛如”,WTF,没错,新名字前加了个&,你没看错,是加了个&,一个崭新的名字就产生了。。。,比如

int iVal = 2^10;
int &refVal = iVal;  //refVal 就是 iVal 另起的名字了【前面有个&】
int &refVal2;    // 错!~ 引用必须先初始化 

!引用即别名,引用不是对象呢,他仅仅仅仅仅仅真的真的真的只是一个对象的别名,我乳名叫 iVal , 大名叫 refVal , &表示refVal 是后有的,大名


废了好大劲,希望让看的人尽量有个深刻的印象,彻底弄明白这货,继续:

引用讲明白了,轮到指针(pointer)了,Pointer 破了他,‘point to’,指向某人,指向某物,指向某种类型。这里看明白没有,和引用相似在于都实现了对其他人的间接访问,当面害羞,只好找个中间人送情书;

关键来了:指针和引用根本就不是一个世界的,其一:指针本身就是个“人”,引用只是给人起别名,指针可以被赋值和拷贝,引用不得行;指针还可以 耍朋友,厌倦了再换,即指向不同的对象/人,但是每次只能指向一个,脚踏两条船是不允许滴;其二,指针可以不用赋初值,引用不得行,他一定有个初值,婴儿和幼儿的区别,婴儿咕咕坠地,啥都不懂,幼儿都有大名了,你说他吃了多少米了都,经事了。比如

int *p1, *p2; //p1,p2 均指向int型对象
double p3, *p4; //p3位double型对象,p4为指向all double 型对象的指针
int p5 = 1, *p6 = &p5; //p6 指向/存放 p5的地址


末了,总结:

(1)指针:指针是一个变量(variable)/对象(object),只不过这个变量 存储/指向 内存的一个  地址/存储单元;而引用跟原来的变量实质上是同一个东西,只不过是原变量(variable)/对象(object)一个别名而已。  

(2)可以有const指针,但是没有const引用;

(3)指针可以有多级,但引用只能是一级(int **p;合法 而 int &&a是不合法的)
(4)指针的值可以为NULL,也可以不用初始化,但引用的值不能为NULL,并且引用在定义之前必须先经过初始化;

(5)指针的值在初始化后可以改变,即指向其它的存储单元,而引用在进行初始化后就不会再改变了。

(6)"sizeof引用"得到的是原来的变量(对象)的大小,而"sizeof指针"得到的是指针本身(所指存储单元对应的内存地址)的大小;

(7)指针和引用的自增(++)运算意义不一样;


…^ - ^… 搬砖验验又何妨,光说不练,上面看起来在玩文字游戏,体现不出多少价值。C++语言中,函数的参数和返回值的传递方式有三种:值传递、指针传递和引用传递。

  • 值传递:下面给出一个“值传递”的示例程序。 fun 函数体内的 x 为main 函数中 变量 i1 的一份拷贝,改变 x 的值不会影响 i1, 所以 i1 的值仍然是3,而 x 的值为3+1=4。【这道题实在是常见啊,很容易错,博主自己也想了好久 -ORZ-】

    #include <iostream>
    //#include <vector>
    using namespace std;
    void fun( int x ){
    	x = x + 1;
    }	
     int main()
    {
    	cout << "请输入1个整数:" << endl;
    	int i1;
    	cin  >> i1;
    	fun( i1 );
    	cout <<"i1 = " << i1 << endl;
    	system("pause");
    	return 0;
    }

  • 引用传递:示例程序如下。 fun 函数体内的 x 为main 函数中 实参i1本身,改变 x 的值将直接 导致 i1变化, 所以 i1 的值仍然是333+1 =334,同样, x 的值为333+1=334.  由此可见,引用作为函数参数进行传递时,实质上传递的是实参本身,即传递进来的不是实参的一个拷贝,因此对形参的修改其实是对实参的修改,所以用引用进行参数传递时,节约时间节约空间!

    #include <iostream>
    //#include <vector>
    using namespace std;
    
    void fun( int &x ){
    	x = x + 1;
    }
    	
     int main()
    {
    	cout << "请输入1个整数:" << endl;
    	int i1;
    	cin  >> i1;
    	fun( i1 );
    	cout <<"i1 = " << i1 << endl;
    	system("pause");
    	return 0;
    }

指针传递: 以下是“指针传递”的示例程序。fun 函数体内的 x 指向/存储/存放 main 函数中变量(对象)i1 的地址(存储单元),改变 指针x 的值(内容) 导致 i1的值(内容)变化, 所以 i1 的值是33+1 =34; x 的值为0x00affb38 {33} -> 0x00affb38 {34}.  

#include <iostream>
//#include <vector>
using namespace std;

void fun( int *x ){
	*x = *x + 1;
}
	
 int main()
{
	cout << "请输入1个整数:" << endl;
	int i1;
	cin  >> i1;
	fun( &i1 );
	cout <<"i1 = " << i1 << endl;
	system("pause");
	return 0;
}





…^ - ^… 细细咀嚼一下上述三个示例程序,你会觉得“引用传递”的性质颇有些类似“指针传递”,而书写方式更加简洁,只比“值传递”多了引用符号,胜在时间和空间。尽管如此,“引用”可以做的任何事情“指针”也都能够做,那为什么还要“引用”,就好比家有电动车,贵是贵了点,充电还又麻烦,但是自行车能做的电动车也能做。那么,“自行车的意义何在?”

我认为,存在即合理,任何东西存在的本质一定有其合理性,用最适当的工具做最恰当的事情;指针就像是一把瑞士军刀,技术到位,上至横扫疆场,下至修剪眉毛,关键是,不是每个程序员都有这个金刚钻,揽不下瓷器活的嘛,指针功能是强大,可稍微不慎,给自己挖坑走上悬崖边边也就分分钟的事。

    某些场合,只是需要借用某变量(对象)的“别名”,那么拿出小刀“引用”就可以了,至于牛刀“指针”,还是放一边晾着的好,以免发生意外。


  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值