引入

C语言中函数有两种传参的方式: 传值和传址。以传值方式, 在函数调用过程中会生成一份临时变量用形参代替, 最终把实参的值传递给新分配的临时变量即形参。 它的优点是避免了函数调用的一些副作用, 但是它无法改变实参的值。函数调用完成之后实参的值不会发生改变, 如果要改变实参的值, 只能通过指针传地址过去。

 void swap (int left, int right)
{
int temp = left;
left = right;
right = temp;
}
void swap (int *_pleft , int * _pRight)
{
assert (NULL ! = _pleft && NULL ! = _pRight) ;
int iTemp = * _pleft;
*_pleft = * _pRight;
*_pRight = iTemp;
13 }

通过传地址的方式是可以解决问题, 但是传指针也有诸多隐患,很容易出现各种“安全事故”。就如同你想剪指甲,别人却给了你一把杀猪刀,这不是大材小用么。因此C++中 引 入了一种新的类型--引用 。引用只是一个别名,它既解决了传值的缺陷,又不具有传地址的隐患,所以应用广泛

 void swap (int& left, int& right)
{
int temp = left;
left = right;
right = temp;
}

引用概念

引用(reference)不是新定义一个变量, 而是给已存在的对象取了 一个别名 ,引用类型,引用另外一种类型。 编译器不会为引用对象新开辟内存空间, 它和它引用的对象共用同一块内存空间 。

 int num = ;
int &number = num; //number指向num(是num的另外一个名字)

一般在初始化变量时,初始值会被拷贝到新建的对象中。在定义引用时程序把引用和他的初始值绑定在一起,而不是将初始值拷贝给引用。一旦初始化完成引用就将和他的初始对象一直绑定在一块(同生共死)。你无法将引用重新绑定到另外一个对象上。

引用即别名

引用并非对象,相反的,它只是为一个已经存在的对象所起的另外一个名字。就好像一个人的名字本来叫张三,然后大家又给他取了一个名字叫阿三,其实张三和阿三是同一个人。定义一个引用之后,对其进行的所有操作都是在与之绑定的对象上进行的:

 number = ;      //把120赋给number指向的对象,此处即是赋给了num
int tmp = number; //与tmp = num执行结果一样

为引用赋值,实际上是把值赋给了与引用绑定的对象。获取引用的值,实际上是获取了与引用绑定的对象的值。同理,以引用作为初始值,实际上是以引用绑定的对象作为初始值。

引用的定义

(1)允许在一条语句中定义多个引用,其中每个引用标识符都必须以&开头;

(2)因为无法将引用重新绑定到另外一个对象上,因此引用必须初始化。

(3)因为引用本身不是一一个对象,所以不能定义引用的引用。

(4)一个变量可以有多个引用,而一个引用只能给一个变量对象 。

(5)引用的类型要和与之绑定的对象严格匹配(不严谨)。

(6)引用只能绑定在对象上而不能和字面值或某个表达式计算的过程绑定在一起。

 int i1 = , i2 =  ;     //i1和i2都是int型
int &r1 = i1, &r2 = i2; //r1和r2都是引用
int &r3 ; //报错:引用必须初始化
int &r4 = i1, &r5 = i2; //r1, r4同为i1的引用,r2, r5同为i2的引用
int &r4 = i2, &r5 = i1; //报错:r4不能同时分别为i1和i2的引用
int &r6 = ; //报错:引用类型的初始值必须是一个对象
double i3 = 3.14;
int &r7 = i3; //报错:此处引用类型的初始值必须是int型对象

引用与指针

相同点:

底层的实现方式相同, 都是按照指针的方式来实现的:

不同点:

(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)引用比指针更安全。不会出现像野指针这样的现象。

指针和引用作为函数参数进行传递时的区别

 #include<iostream>
using namespace std; void swap(int *a,int *b)
{
  int temp=*a;
  *a=*b;
  *b=temp;
}
int main(void)
{
  int a=,b=;
  swap(&a,&b);
  cout<<a<<" "<<b<<endl;
  system("pause");
  return ;
}

输出结果为:20  10

  用指针传递参数,可以实现对实参进行改变的目的,是因为传递过来的是实参的地址,因此使用*a实际上是取存储实参的内存单元里的数据,即是对实参进行改变,因此可以达到目的。

但是请看下面这个程序:

 void test(int *p)
{
  int a=;
  p=&a;
  cout<<p<<" "<<*p<<endl;
}
int main(void)
{
int *p=NULL;
test(p);
if(p==NULL)
cout<<"指针p为NULL"<<endl;
system("pause");
return ;
}

运行结果为:

0x22ff44 1

指针p为NULL

  为什么会这样呐?不是传递的地址么,怎么 p 会是NULL?事实上,在 main 函数中声明了一个指针p,并赋值为NULL,当调用 test 函数时,事实上传递的也是地址,只不过传递的是值地址。什么意思呢?也就是说将指针作为参数进行传递时,实际上和传值形式的传参是相同的,只不过拷贝的的是地址。当把指针作为参数进行传递时,也是将实参的一个拷贝传递给形参,即上面程序 main 函数中的 p 和 test 函数中使用的 p 不是同一个变量,存储2个变量 p 的单元也不相同,即两个指针它们自己的地址不同(只是2个 p 指向同一个存储单元,里面保存的是同样的值),那么在 test 函数中对 p 进行修改,并不会影响到 main 函数中的 p 的值。

如果要想达到同时修改 main 函数中 p 的目的,就得使用二级指针或者引用了。

 void test(int *&p)
{
  int a=;
  p=&a;
  cout<<p<<" "<<*p<<endl;
}
int main(void)
{
int *p=NULL;
test(p);
if(p!=NULL)
cout<<"指针p不为NULL"<<endl;
system("pause");
return ;
}

输出结果为:0x22ff44 1

指针p不为NULL

  引用作为函数参数进行传递时,实质上传递的是实参本身,即传递进来的不是实参的一个拷贝,因此对形参的修改其实是对实参的修改,所以在用引用进行参数传递时,不仅节约时间,而且可以节约空间。

参考:http://www.cnblogs.com/dolphin0520/

引用的作用&引用与指针的区别的更多相关文章

  1. Java中到底有没有指针;同时注意引用和指针的区别

    Java中引用的作用类似于指针,但是有区别:()    (1) 指针必然指向一个内存地址,如果你定义的时候不指定,就会乱指(很可能造成安全隐患)但是引用定义出来后默认指向为空.     (2) 指针可 ...

  2. C语言学习笔记 (002) - C++中引用和指针的区别(转载)

    下面用通俗易懂的话来概述一下: 指针-对于一个类型T,T*就是指向T的指针类型,也即一个T*类型的变量能够保存一个T对象的地址,而类型T是可以加一些限定词的,如const.volatile等等.见下图 ...

  3. Java的引用和C++的指针de区别

    Java的引用和C++的指针都是指向一块内存地址的,通过引用或指针来完成对内存数据的操作,就好像风筝的线轴一样,通过线轴总是能够找到风筝,但是它们在实现,原理作用等方面却有区别. (1)类型:引用其值 ...

  4. c++中的引用与指针的区别

    http://blog.csdn.net/lyd_253261362/article/details/4323691 c++中的引用与指针的区别 ★ 相同点: 1. 都是地址的概念: 指针指向一块内存 ...

  5. C++中引用与指针的区别(详细介绍)

    C++中引用与指针的区别(详细介绍) C++中的引用与指针的区别   指向不同类型的指针的区别在于指针类型可以知道编译器解释某个特定地址(指针指向的地址)中的内存内容及大小,而void*指针则只表示一 ...

  6. [ZZ]C++中,引用和指针的区别

    (1) 引用总是指向一个对象,没有所谓的 null reference .所有当有可能指向一个对象也由可能不指向对象则必须使用 指针. 由于C++ 要求 reference 总是指向一个对象所以 re ...

  7. 转:C++中引用传递与指针传递区别

    从概念上讲.指针从本质上讲就是存放变量地址的一个变量,在逻辑上是独立的,它可以被改变,包括其所指向的地址的改变和其指向的地址中所存放的数据的改变. 而引用是一个别名,它在逻辑上不是独立的,它的存在具有 ...

  8. c++引用与指针的区别

    c++引用与指针的区别 ★ 相同点: 1. 都是地址的概念: 指针指向一块内存,它的内容是所指内存的地址:引用是某块内存的别名. 指针的权威定义: In a declaration T D where ...

  9. <转>c++引用与指针的区别(着重理解)

     ★ 相同点: 1. 都是地址的概念: 指针指向一块内存,它的内容是所指内存的地址:引用是某块内存的别名.  ★ 区别: 1. 指针是一个实体,而引用仅是个别名: 2. 引用使用时无需解引用(*),指 ...

随机推荐

  1. Maven入门项目创建

    项目构建 1.新建maven项目 2.跳过骨架选择,如果不跳过骨架选择创建出的项目目录是不全的(骨架其实就是项目的模板) 3.Group Id,Artifact Id,Version称为项目的坐标,当 ...

  2. scrapy基础 之 爬虫入门:先用urllib2来理解爬虫

    1,概念理解 爬虫:抓取和保存网页信息,用户看到的网页实质是由 HTML 代码构成的,爬虫爬来的便是这些内容,通过分析和过滤这些 HTML 代码,实现对图片文字等资源的获取. URL:即统一资源定位符 ...

  3. Django入门------基础(1)

    基础 Django 是用 Python 写的一个自由和开放源码 web 应用程序框架.web框架是一套组件,能帮助你更快.更容易地开发web站点.当你开始构建一个web站点时,你总需要一些相似的组件: ...

  4. SQLServer常用分页方式

    mysql的分页是基于limit关键字,oracle的分页是基于rownum行号,SQLserver的分页在下面进行研究,是基于SQLServer2012进行的测试. 0.原来的SQL的所有数据 下面 ...

  5. Markdown超链接及脚注

    Markdown链接及脚注 [时间:2017-02] [状态:Open] [关键词:markdown,标记语言,页内链接,超链接,脚注] 本文内容来自Markdown 11种基本语法,仅对其中我不熟悉 ...

  6. 【转】MySQL— 进阶

    [转]MySQL— 进阶 目录 一.视图 二.触发器 三.函数 四.存储过程 五.事务 一.视图 视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需 ...

  7. Delphi 实现自动更新

    Delphi 通用程序自动更新升级:http://www.delphitop.com/html/wangluo/2968.html https://www.cnblogs.com/hnxxcxg/p/ ...

  8. c# partial 分部类和分部方法

    一.partial 它是一个关键字修饰符.可以将类或结构.接口或方法的定义拆分到两个或更多个源文件中. 每个源文件包含类型或方法定义的一部分,编译应用程序时将把所有部分组合起来.修饰符不可用于委托或枚 ...

  9. MYSQL添加远程用户或允许远程访问

    1.用root用户登陆 格式:grant 权限 on 数据库教程名.表名 to 用户@登录主机 identified by "用户密码";             @ 后面是访问M ...

  10. 基于OpenSSL自建CA和颁发SSL证书

    关于SSL/TLS介绍见文章 SSL/TLS原理详解.关于证书授权中心CA以及数字证书等概念,请移步 OpenSSL 与 SSL 数字证书概念贴 . openssl是一个开源程序的套件.这个套件有三个 ...