这是老师上课讲的内容,现在把它写下来,一方面当做复习,另一方面真的想学点东西。废话不多说,先贴上测试的代码:

 #include <iostream.h>

 float temp;

 float fn1(float r)
{
temp = (float)(r*r*3.14);
return temp;
} float& fn2(float r) //绑定return的变量
{
//float temp; temp = (float)(r*r*3.14);
return temp;
} void main()
{
float a=fn1(5.0); //
float& b=fn1(5.0); //VC++ 6.0 error, (有的编译器warning)
float c=fn2(5.0); //
float& d=fn2(5.0); //如果temp不是全局变量,仍可能有问题
}

在分析上面的代码之前,先说两个理论:

(一)什么是引用。同时借助老师的简单比喻:

一个变量的引用就是这个变量的别名,引用在定义的时候必须同时初始化。老师是这样比喻的,说他有个同学(具体有无此人,无从考证)个子很矮,所以好多人给老段起了个外号叫做根号2,当然了根号2和老段是同一个人,对老段的任何操作都是对根号2的操作。后来又有人给根号2(也就是老段)起了另一个外号叫做矮冬瓜。这样,根号2、老段和矮冬瓜指的就是同一个人了。这里的老段就象征着变量的本体,根号2就是老段的引用,矮冬瓜就是老段的引用的引用。当然了,这三个称谓表示同一个人。

(二)一个函数的声明类型和它具体的返回值类型的关系:

首先知道一点:函数的返回值在内存的栈空间中是要开辟空间的。假设我们给这个空间起个名字叫做END,那么这个END的类型就是函数声明的时候的返回类型,不管你具体实际中返回的是什么类型。例如上面的fn2()函数:

 float temp;
float& fn2(float r) //绑定return的变量
{ temp = (float)(r*r*3.14);
return temp;
}

函数返回的时候具体的语法是:float & END = temp;其中float就是这个函数声明时的类型,END就是给函数返回开辟的栈空间,temp就是实际return的东西。这就是用return的temp初始化END引用。这里temp就是老段,END就是根号2。

----------------------------------------------------------------------------------------------------------------------------------------

下面逐个的分析最开始的代码:

(1)

 float a = fn1(5.0);

函数返回时的语法为:float END= temp;这样END就是一个float类型的变量。上面的这句代码就是用END这个变量初始化a。随后调用结束,栈空间的END就被os收回了。

(2)

 float &b = fn1(5.0);

END为float类型的,函数返回时具体的语法是:float END= temp;这里的END也是一个float类型的变量。上面的这句代码在main函数中给END弄了一个引用(内部用指针实现的)。这里的b是个引用,也就是根号2,END就是老段。但是问题来了,END是暂时的栈空间啊,函数调用结束后它就被清除了啊,相当于在main函数的栈空间中弄了一个指针,但是这个指针指向了一个即将被清除的变量。当然会报错。

(3)

 float c = fn2(5.0);

这里的END就是一个引用了,因为fn2声明的时候类型为float &。函数返回时的语法是:float & END = temp;用temp初始化一个引用。这里的END就是根号2,temp就是老段,也就是说对根号2的任何操作都会作用在老段的身上(他们是同一个东西)。所以这个语句的意思就是用temp给c初始化。

(4)

 float &d = fn2(5.0);

同样END是引用,这里是用一个引用初始化另一个引用。这时temp是老段,END是根号2,d是矮冬瓜,三个名字说的是同一个人。即使调用结束后,END被清掉了,但是他毕竟是别名,不是变量的本尊,所以不会报错。

-----------------------------------------------------------------------------------------------------------------------------------------

注:作用在引用上的操作,同样会作用在变量本身上,但是如果这个引用的生存期到了,它要消亡了,这是没有关系的。就好像,忽然有一天大家都不在管老段叫根号2,那么根号2这个外号的生存期就到头了。但是这没什么影响。

但是老段不能消亡,你说老段消亡了,但是根号2这个外号还在,那不行,根号2指的是谁啊。

引用理论上是不占内存空间的,但是实际的实现上就是指针的操作。只不过这种指针的操作对编程人员是透明的。

C++引用和函数返回值的更多相关文章

  1. 【C/C++】引用&的含义/语法/作为函数参数/函数返回值/本质/常量引用

    含义 引用不产生副本,只是给原变量起了别名. 对引用变量的操作就是对原变量的操作. 基本语法 数据类型 &别名 = 原名 e.g. int a = 10; int &b = a; // ...

  2. PHP获取函数返回值的引用

    通过在函数前添加&可以获取函数返回值的引用,如:function &test(){return 10;}

  3. 函数返回值为 const 指针、const 引用

    函数返回值为 const 指针,可以使得外部在得到这个指针后,不能修改其指向的内容.返回值为 const 引用同理. class CString { private: char* str; publi ...

  4. 速战速决 (3) - PHP: 函数基础, 函数参数, 函数返回值, 可变函数, 匿名函数, 闭包函数, 回调函数

    [源码下载] 速战速决 (3) - PHP: 函数基础, 函数参数, 函数返回值, 可变函数, 匿名函数, 闭包函数, 回调函数 作者:webabcd 介绍速战速决 之 PHP 函数基础 函数参数 函 ...

  5. C++ const修饰函数、函数参数、函数返回值

    const修饰函数 在类中将成员函数修饰为const表明在该函数体内,不能修改对象的数据成员而且不能调用非const函数.为什么不能调用非const函数?因为非const函数可能修改数据成员,cons ...

  6. C++函数返回值(02)

    对象作为返回值 编译器会将函数栈中的返回值数据拷贝到返回栈中 指针作为返回值 函数的返回值可以是存储某种类型数据的内存地址,称这种函数为指针函数.它们的一般定义形式如下:  类型标识符 *函数名(参数 ...

  7. C++函数返回值发生的对象复制

    最近用QT做一个监控系统的项目,需要显示目标的运动轨迹,每次目标移动后,就在目标的轨迹中(用vector记录)添加一条新轨迹. 但是在运行中画面里一直不出现轨迹,经过调试发现是记录轨迹的函数出错了. ...

  8. Python第七天 函数 函数参数 函数里的变量 函数返回值 多类型传值 函数递归调用 匿名函数 内置函数

    Python第七天   函数  函数参数   函数里的变量   函数返回值  多类型传值     函数递归调用   匿名函数   内置函数 目录 Pycharm使用技巧(转载) Python第一天   ...

  9. 转 Perl函数返回值用法指导

    http://developer.51cto.com/art/201007/213003.htm Perl函数返回值用法指导   Perl编程语言中Perl函数返回值用法你是否比较熟悉,这里向大家简单 ...

随机推荐

  1. UVALive 6665 Dragonas Cruller

    题目链接:https://icpcarchive.ecs.baylor.edu/external/66/6665.pdf 题目大意: 有一个3 * 3 的格子: 每个格子上面的数字能够朝上下左右四个方 ...

  2. InterLockedIncrement and InterLockedDecrement函数原理

    实现数的原子性加减. 什么是原子性的加减呢? 举个样例:假设一个变量 Long value =0; 首先说一下正常情况下的加减操作:value+=1. 1:系统从Value的空间取出值,并动态生成一个 ...

  3. InfluxDB 开源分布式时序、事件和指标数据库

    InfluxDB 是一个开源分布式时序.事件和指标数据库.使用 Go 语言编写,无需外部依赖.其设计目标是实现分布式和水平伸缩扩展. 特点 schemaless(无结构),可以是任意数量的列 Scal ...

  4. js 获取asp:dropdownlist选中的值

    var eSection = document.getElementById("<%=tx_ddlType.ClientID%>"); var eSectionValu ...

  5. 整理HTML的一些基础

    HTML,超文本标记语言(HyperText Markup Language) 超文本:指页面内可以包含图片.链接.音乐.程序等非文字元素 标记:页面的由各种标签(标记)组成,文本有隐藏的文本标签 H ...

  6. php之Cookie与Session详解

    Cookie管理 Cookie是在HTTP协议下,通过服务器或脚本语言可以维护客户浏览器上信息的一种方式,Cookie的使用很普遍,许多提供个人化服务的网站都是利用Cookie来区别不同用户,以显示与 ...

  7. 使用PowerShell管理Windows8应用

    引子(?): 我从消费者预览版开始使用的win8,大概是因为我年龄不大的缘故,我很快熟悉了这个操作系统并习惯了使用windows8的Modern App.我之前使用过一个叫Windows8 Moder ...

  8. 如何对MySQL 对于大表(千万级)进行优化

    如何对Mysql中的大型表进行优化 @(mysql 笔记) 收集信息 1.数据的容量:1-3年内会大概多少条数据,每条数据大概多少字节: 2.数据项:是否有大字段,那些字段的值是否经常被更新: 3.数 ...

  9. eclipse 使用maven 创建springmvc + mybatis

    接着eclipse 使用maven 创建纯spring mvc项目 毕竟项目都要访问数据库的, 所以加上mybatis的支持也就是网上大多时候说的 SSM框架的搭建(Spring + Spring M ...

  10. mysql explain 命令简解

    参考官方文档地址: http://dev.mysql.com/doc/refman/5.7/en/explain.html 为什么用explain . 如果你的页面返回结果很慢,你就需要使用expla ...