函数返回值时,要生成一个值的副本。

而用引用返回值时,不生成值的副本。

  例如,下面的程序是有关引用返回的4种形式:
    //*********************
    //**   ch9_6.cpp  **
    //*********************

    #include <iostream.h>

    float temp;

    float fn1(float r)
    {
     temp = r*r*3.14;
     return temp;
    }

    float& fn2(float r)
    {
     temp = r*r*3.14;
     return temp;
    }

    void main()
    {
     float a=fn1(5.0); //1
     float& b=fn1(5.0); //2:warning
     float c=fn2(5.0); //3
     float& d=fn2(5.0); //4
     cout<<a<<endl;
     cout<<b<<endl;
     cout<<c<<endl;
     cout<<d<<endl;
    }

  运行结果为:
    78.5
    78.5
    78.5
    78.5

  对主函数的4种引用返回的形式, 程序的运行结果是一样的。但是它们在内存中的活动情况是各不相同的。其中变量temp是全局数据,驻留在全局数据区data。函数main()、函数fnl()或函数fn2()驻留在栈区stack。

  第一种情况:见图9-5。


图9-5 返回值方式的内存布局

  这种情况是一般的函数返回值方式。 返回全局变量temp值时,C++创建临时变量并将temp的值78.5复制给该临时变量。返回到主函数后,赋值语句a=fnl(5.0)把临时变量的值78.5复制给a。

第二种情况:见图9-6。


图9-6 返回值初始引用的情形

  这种情况下,函数fnl()是以值方式返回的,返回时, 复制temp的值给临时变量。返回到主函数后,引用b以该临时变量来初始化,使得b成为该临时变量的别名。由于临时变量的作用域短暂,所以b面临无效的危险。 根据C++标准,临时变量或对象的生命期在一个 完整的语句表达式结束后便宣告结束,也即在“float& b=fnl(5.0);”之后,临时变量不再存在。 所以引用b以后的值是个无法确定的值。BC对C++标准进行了扩展,规定如果临时变量或对象作为引用的初始化时,则其生命期与该引用一致。14.7节将进一步介绍这一内容。 这样的程序, 依赖于编译器的具体实现,所以移植性是差的。
  若要以返回值初始化一个引用,应该先创建一个变量,将函数返回值赋给这个变量,然 后再以该变量来初始化引用,就像下面这样:
    int x=fnl(5.0);
    int& b=x;

  第三种情况:见图9-7。


图9—7 返回引用方式

  这种情况,函数fn2()的返回值不产生副本,所以, 直接将变量temp返回给主函数。主函数的赋值语句中的左值,直接从变量temp中得到复制,这样避免了临时变量的产生。当变量temp是一个用户自定义的类型时,这种方式直接带来了程序执行效率和空间利用的利益。

第四种情况:见图9-8。


图9—8 返回引用方式的值作为引用的初始化

  这种情况, 函数fn2()返回一个引用,因此不产生任何返回值的副本。在主函数中,一个引用声明d用该返回值来初始化,使得d成为temp的别名。由于temp是全局变量, 所以在d的有效期内temp始终保持有效。这样做法是安全的。

P.S.

但是, 如果返回不在作用域范围内的变量或对象的引用, 那就有问题了。这与返回一个局部作用域指针的性质一样严重。BC作为编译错误,VC作为警告,来提请编程者注意。例如,下面的代码返回一个引用,来给主函数的引用声明初始化:
    float& fn2(float r)
    {
     float temp;
     temp=r*r*3.14;
     return temp;
    }
    void main()
    {
     float &d=fn2(5.0); //error返回的引用是个局部变量
    }

  见图9-9说明。


图9-9 返回的引用是局部变量

  如果返回的引用是作为一个左值进行运算,也是程序员最犯忌的。所以,如果程序中有下面的代码,则一定要剔除:
    float& fn2(float r)
    {
     float temp;
     temp=r*r*3.14;
     return temp;
    }
    void main()
    {
     fn2(5.0)=12.4; //error返回的是局部作用域内的变量
    }

文自:http://blog.csdn.net/tcdddd/article/details/5519332

函数的返回值是如何带出和接收的以及内存中的活动情况.RP的更多相关文章

  1. C语言中函数的返回值

    规则 除局部变量的内存地址不能作为函数的返回值外,其他类型的局部变量都能作为函数的返回值. 我总结出下面这些规则: int.char等数据类型的局部变量可以作为函数返回值. 在函数中声明的指针可以作为 ...

  2. c++特性:指向类成员的指针和非类型类模板参数和函数指针返回值 参数推导机制和关联型别

    一.c++允许定义指向类成员的指针,包括类函数成员指针和类数据成员指针 格式如下: class A { public: void func(){printf("This is a funct ...

  3. Python的函数式编程-传入函数、排序算法、函数作为返回值、匿名函数、偏函数、装饰器

    函数是Python内建支持的一种封装,我们通过把大段代码拆成函数,通过一层一层的函数调用,就可以把复杂任务分解成简单的任务,这种分解可以称之为面向过程的程序设计.函数就是面向过程的程序设计的基本单元. ...

  4. Flask实战第6天:视图函数Response返回值

    视图函数的返回值会被自动转换为一个响应对象,Flask的转换逻辑如下: 如果返回的是一个合法的响应对象,则直接返回 可以使用make_response函数来创建Response对象,这个方法可以设置额 ...

  5. python -- 初始函数 函数的定义,函数的返回值以及函数的参数

    1.什么是函数,函数的定义及语法 2.函数的返回值 3.函数的参数 一.函数的定义及语法 函数的定义:定义了一个动作或者功能,是对功能的封装 语法: def 函数名( 形参列表 ):          ...

  6. 获取JavaScript异步函数的返回值

    今天研究一个小问题: 怎么拿到JavaScript异步函数的返回值? 1.错误尝试 当年未入行时,我的最初尝试: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <s ...

  7. 6.1 函数的返回值、匿名函数lambda、filter函数、map函数、reduce函数

      函数的返回值: 函数一旦执行到   return,函数就会结束,并会返回return 后面的值,如果不使用显式使用return返回,会默认返回None . return None可以简写为   r ...

  8. Swift2.0语言教程之函数的返回值与函数类型

    Swift2.0语言教程之函数的返回值与函数类型 Swift2.0中函数的返回值 根据是否具有返回值,函数可以分为无返回值函数和有返回值函数.以下将会对这两种函数类型进行讲解. Swift2.0中具有 ...

  9. C++函数的返回值——返回引用类型&非引用类型

    函数的返回主要分为以下几种情况: 1.主函数main的返回值: 允许主函数main没有返回值就可结束:可将主函数main返回的值视为状态指示器,返回0表示程序运行成功,其他大部分返回值则表示失败. 2 ...

随机推荐

  1. uva10892(暴力枚举)

    把n的所有因子求出来,总数不会太多,所以直接O(n2)的暴力枚举所有对行不行. 有几个细节要注意,详见代码. #include<iostream> #include<cstdio&g ...

  2. hihocoder #1138 : Islands Travel

    题意,求1到n的最短路.不难想到单源最短路,难点在于数量级太大,因此如何建图是关键: 因为cost = min{|Xi-Xj|, |Yi-Yj|}:所以,点i的移动只有两种情况,. x距离最近的点,. ...

  3. volatile关键字及内存可见性

    先看一段代码: package com.java.juc; public class TestVolatile { public static void main(String[] args) { T ...

  4. python exec内置表达式--exec()

    exec obj功能: exec 执行储存在字符串或文件中的Python语句,相比于 eval,exec可以执行更复杂的 Python 代码.obj 是 要执行的表达式.exec 返回值永远为 Non ...

  5. 什么是 PCB 的压适孔

    引用 AMOBBS 1 再举一个高成本控制的例子:有类PCB产品对孔径要求极度严格,这类孔叫压适孔,这类孔的作用类似于显卡内存条的插座,能刚刚好被元件插上,而且元件不会掉,PTH的压适孔公差要求为-0 ...

  6. 推荐几本学习MySQL的好书

    转载:http://mingxinglai.com/cn/2015/12/material-of-mysql/ 我这里推荐几本MySQL的好书,应该能够有效避免学习MySQL的弯路,并且达到一个不错的 ...

  7. 关于postman、postman interceptor的安装、配置问题

    由于app中有一些鉴权问题,需要携带浏览器的cookie. 不然的话不能够正确测试接口,就在chrome(这里下载的来源是Google商店)中添加了postman interceptor插件. 然后发 ...

  8. Windows10:怎么安装whl文件

    whl格式本质上是一个压缩包,里面包含了py文件,以及经过编译的pyd文件.使得可以在不具备编译环境的情况下,选择合适自己的python环境进行安装.安装方法很简单,进入命令行输入pip instal ...

  9. 四川第七届 D Vertex Cover(二分图最小点覆盖,二分匹配模板)

    Vertex Cover frog has a graph with nn vertices v(1),v(2),…,v(n)v(1),v(2),…,v(n) and mm edges (v(a1), ...

  10. 2016.3.7 Word2007编号设置

    1.点击下图红圈出的下拉箭头 2.点击下图新建样式按钮 3.在弹出窗口中,设置名称AAA(方便稍后的查找修改),样式类型改为列表,点击编号 4.在弹出的窗口中以此设置各级标题的编号样式,保存后设置成功 ...