一、引用的概念

引用就是某一变量(目标)的一个别名,对引用的操作与对变量直接操作完全一样。引用的声明方法:
 类型标识符 &引用名 = 目标变量名;

为一个变量起一个别名。假如有一个变量a,想给它起一个别名b,可以这样写:

 int a;             //定义a是整型变量
int &b=a; //声明b是a的引用

二、引用的一些规则

(1)引用被创建的同时必须被初始化,指针则可以在任何时候被初始化。
(2)不能有NULL引用,引用必须与合法的存储单元关联,指针则可以是NULL。在使用引用之前不需要测试它的合法性。相反,指针则应该总是被测试,防止其为空。
(3)一旦引用被初始化,就不能改变引用的关系,但是指定的对象其内容可以改变。指针可以被重新赋值以指向另一个不同的对象。

例1:

void main()
{
int a1;
int &ra; // error C2530: “ra”: 必须初始化引用
}

例2:

void main()
{
int a1, a2;
int &ra = a1;
int &ra = a2; // error C2374: “ra”: 重定义;多次初始化
}

企图使b又变成a2的引用(别名)是不行的。

例3:

int main()
{
int x=;
void &rx=x; // error C2182: “rx”: 非法使用“void”类型
int a[];
int &ra[]=a; // error C2234: “ra”: 引用数组是非法的
return ;
}

上例中的两处错误说明:void修饰是不能够声明引用的,引用是不能够声明数组的,即不能够声明引用数组。

在任何情况下都不能使用指向空值的引用,一个引用必须总是指向某些对象。因此如果使用一个变量并让它指向一个对象,但是该变量在某些时候也可能不指向任何对象,这时候应该把变量声明为指针,因为这样可以赋予空值给该变量。相反,如果变量肯定指向一个对象,这时候就可以把变量声明为引用。不存在指向空值的引用这个事实意味着使用引用的代码效率比指针要高。

三、常引用

常引用声明方式:
   const 类型标识符 &引用名 = 目标变量名;
用这种方式声明的引用,不能通过引用对目标变量的值进行修改,从而使引用的目标成为const,达到了引用的安全性。

例:

int main()
{
int a;
const int &ra=a;
ra=; // error C3892: “ra”: 不能给常量赋值
a=; // OK
return ;
}

在C++面向对象程序设计中,经常用常指针和常引用作函数参数。这样既能保证数据安全,使数据不能被随意修改,在调用函数时又不必建立实参的拷贝。

四、引用之间的赋值

例:

int main()
{
int a = ;
int b = ;
printf("a = %d\n",a);
printf("b = %d\n",b);
printf("a address is:%d\n",&a);
printf("b address is:%d\n",&b);
printf("give reference for a and b\n");
int &ra = a;
int &rb = b;
printf("ra = %d\n",ra);
printf("rb = %d\n",rb);
printf("ra address is:%d\n",&ra);
printf("rb address is:%d\n",&rb);
printf("let ra = rb\n");
ra = rb;
printf("a = %d\n",a);
printf("b = %d\n",b);
printf("ra = %d\n",ra);
printf("rb = %d\n",rb);
printf("a address is:%d\n",&a);
printf("b address is:%d\n",&b);
printf("ra address is:%d\n",&ra);
printf("rb address is:%d\n",&rb);
return ;
}

程序执行结果为:
a = 1
b = 2
a address is: 0031f870
b address is: 0031f864
give reference for a and b
ra = 1
rb = 2
ra address is: 0031f870
rb address is: 0031f864
let ra = rb
a = 2
b = 2
ra = 2
rb = 2
a address is: 0031f870
b address is: 0031f864
ra address is: 0031f870
rb address is: 0031f864

从上例可知,虽然引用被初始化后,便不能改变引用的关系;但是,可以用给它赋值其它引用。引用之间赋值并不改变引用和被引用变量的地址,只改变了引用对象值 。

五、指针的引用

指针的引用就是某一指针的一个别名,对引用的操作与对指针直接操作完全一样。指针引用的声明方法:
  类型标识符 *&引用名 = 目标变量名;
在某种意义上,"*"和"&"是意思相对的两个东西,把它们放在一起有什么意义呢?。在某种程度上,指针的引用类似于二级指针(指针的指针)。

int main()
{
int x = ;
int *px = &x; //x的指针
int *& rpx = px; //x的指针的引用
int y = ;
int *py = &y; //y的指针
int *& rpy = py; //y的指针的引用
cout<<"x: "<<x<<endl cout<<"px:"<<px<<endl;
cout<<"rpx: "<<rpx<<endl;
cout<<"y: "<<y<<endl;
cout<<"py:"<<py<<endl;
cout<<"rpy: "<<rpy<<endl;
cout<<"-------------------"<<endl;
*rpx = *rpy;
cout<<"x: "<<x<<endl;
cout<<"px:"<<px<<endl;
cout<<"rpx: "<<rpx<<endl;
cout<<"y: "<<y<<endl;
cout<<"py:"<<py<<endl;
cout<<"rpy: "<<rpy<<endl;
return ;
}

程序执行结果为:
x:10
px:0013FF60
rpx:0013FF60
y:20
py:0013FF3C
rpy:0013FF3C
-------------------
x:20
px:0013FF60
rpx:0013FF60
y:20
py:0013FF3C
rpy:0013FF3C

输出说明*rpx = *rpy之间的赋值并未改变指针引用的值,即地址的值,而是改变了引用对象的值 。

若将上例中*rpx = *rpy;改为:
  rpx = rpy;
程序执行结果为:
x:10
px:0013FF60
rpx:0013FF60
y:20
py:0013FF3C
rpy:0013FF3C
-------------------
x:10
px: 0013FF3C
rpx: 0013FF3C
y:20
py:0013FF3C
rpy:0013FF3C

输出说明,指针引用之间的赋值只改变指针的值,引用对象的值没有改变

指针和引用

引用类型和指针类型都可以实现通过一个变量访问另一个变量,但访问的语法形式不同:

引用采用的是直接访问形式,指针采用间接访问形式。

除了在定义时指定的被引用变量外,引用类型变量不能再引用其它变量;而指针变量定义后可以指向其它同类型的变量。因此,引用类型比指针类型要安全。

C++ 函数 引用的更多相关文章

  1. Jmeter外部函数引用

    Jmeter外部函数引用 1.Beanshell引用Jmeter变量 添加用户自定义变量,输入变量名称和变量值,添加Debug sampler,用于输出初始变量值.

  2. perl 回调必须是函数引用

    [root@wx03 lib]# cat a1.pl use AE; use AnyEvent; ##定义watch my $t = AnyEvent->timer( after => 0 ...

  3. 【足迹C++primer】48、函数引用操作符

    函数引用操作符 struct absInt { int operator()(int val) const { cout<<val<<"<->!!!&qu ...

  4. PHP中静态变量和函数引用返回

    这两天看看PHP写的框架CI,源代码中写了很多静态变量和函数引用. 官方文档地址:http://php.net/manual/zh/language.references.return.php 简单写 ...

  5. php引用(&)变量引用,函数引用,对象引用和参数引用用法

    php引用(&)变量引用,函数引用,对象引用和参数引用用法   php的引用(就是在变量或者函数.对象等前面加上&符号) 在PHP 中引用的意思是:不同的名字访问同一个变量内容.与C语 ...

  6. 【DB2】SQL0501N FETCH 语句或 CLOSE 语句中指定的游标尚未打开,或者游标标量函数引用中的游标变量尚未打开。 SQLSTATE=24501

    在DB2中建立存储过程时使用了隐式游标,在调用的时候报错如下: SQL0501N  FETCH 语句或 CLOSE 语句中指定的游标尚未打开,或者游标标量函数引用中的游标变量尚未打开.  SQLSTA ...

  7. KClass与函数引用详解

    继续学习Kotlin反射相关的东东. KClass: 在上一次是通过类来获取它的KClass对象: 那如果是一个对象呢?与这个对象对应的类的KClass对象又是如何获取的呢?像Java也是一样有相关机 ...

  8. php中引用&的真正理解-变量引用、函数引用、对象引用

    php的引用(就是在变量或者函数.对象等前面加上&符号) //最重要就是 删除引用的变量 ,只是引用的变量访问不了,但是内容并没有销毁 在PHP 中引用的意思是:不同的名字访问同一个变量内容. ...

  9. C++ primer(八)--内联函数 引用变量 引用传递函数参数 函数重载/模板/模板具体化

    一.内联函数     常规函数和内联函数的区别在于C++编译器如何将他们组合到程序中.编译过程的最终产品是可执行程序--由一组机器语言指令组成.运行程序时,操作系统将这些指令载入到计算机内存中,因此每 ...

  10. Jmeter函数引用和函数重定向

    在jmeter中的[选项]中选择[函数助手对话框]---这些函数可以高速有效的帮助我们开展自动化编写与校验!!!!!! 如图: 重点!!!本章的侧重点不讲函数的具体使用,函数具体的使用与java类似, ...

随机推荐

  1. PAT乙级1026

    1026 程序运行时间 (15 分)   要获得一个 C 语言程序的运行时间,常用的方法是调用头文件 time.h,其中提供了 clock() 函数,可以捕捉从程序开始运行到 clock() 被调用时 ...

  2. [图解tensorflow源码] Session::Run()流程图 (单机版)

  3. iOS 多线程:『GCD』详尽总结

    本文用来介绍 iOS 多线程中 GCD 的相关知识以及使用方法.这大概是史上最详细.清晰的关于 GCD 的详细讲解+总结的文章了.通过本文,您将了解到: 1. GCD 简介 2. GCD 任务和队列 ...

  4. 在element-ui的select下拉框加上滚动加载

    在项目中,我们需要运用到很多来自后端返回的数据.有时是上百条,有时甚至上千条.如果加上后端的多表查询或者数据量过大,这就导致在前端的显示就会及其慢,特别是在网络不好的时候更是如此. 自然,后端就做了一 ...

  5. .NET中Quartz任务调度器的简单应用实例

    1.首先从NuGet中安装Quartz,安装最新版本就OK 2.新建一个Job类实现Quart中的IJob接口用于执行业务逻辑,代码如下: class CheckUpdateJob : IJob { ...

  6. php如何实现统计一个数字在排序数组中出现的次数(代码)

    统计一个数字在排序数组中出现的次数. 博客 www.51msk.cn 1.有序的数组查找,使用二分法2.二分法查找第一次出现的位置,二分法查找最后一次出现的位置,end - start +1 left ...

  7. 改用固定IP后zabbix无法发送邮件的问题解决

    虚拟机之前一直用随机IP,然后发送邮件也正常. 改成固定IP以后,发送邮件失败. 用mail命令发送邮件成功. 查看zabbix_server的log,显示 cannot connect to SMT ...

  8. 大数据入门第七天——MapReduce详解(二)切片源码浅析与自定义patition

    一.mapTask并行度的决定机制 1.概述 一个job的map阶段并行度由客户端在提交job时决定 而客户端对map阶段并行度的规划的基本逻辑为: 将待处理数据执行逻辑切片(即按照一个特定切片大小, ...

  9. # 课下测试ch02

    课下测试ch02 1.假设下面位串是基于IEEE格式的5位浮点表示,一个符号位,2个阶码位,两个小数位.下面正确的是(AD) A . 3.5的表示是[01011] B . -1.0的表示[01111] ...

  10. 准确率,召回率,F值

    下面简单列举几种常用的推荐系统评测指标: 1.准确率与召回率(Precision & Recall) 准确率和召回率是广泛用于信息检索和统计学分类领域的两个度量值,用来评价结果的质量.其中精度 ...