按值传递

地址传递:

应该明白只有这2种传递,下面讨论函数的按值传递

#include <stdio.h>
#include <stdlib.h>
int add_rtVal(int a,int b)
{
int c = 0;
c = a + b;
return c;
}
int main(int argc,char* argv[])
{
int a = 0,b = 0;
int c = 0;
a = 3;
b = 5;
c = add_rtVal(a,b);
printf("c=%d/n",c); return 1;
}

这个地方是正确返回了,测试c也对,why?我们返回的是一个值 ,在返回值后我们将其赋给了变量C,相当于创建了一个副本,不论add()中的局部变量是否销毁都没有关系了。

但是如果我们返回的是一个地址,指向局部变量的地址,就不行了。因为局部变量的地址在函数调用完成后销毁,我们返回的地址就指向的区域内就不是我们想要的值了,因为这块区域已是公共的,可被其它函数占用的,其内容是不定的。看如下例子:

#include <stdio.h>
#include <stdlib.h>
char* hello()
{
char p[]= "hello world";
return p;
}
int main(int argc,char argv[])
{
char *str; str = hello();
printf("%s/n",str);
return 1;
}

结果:"/n
Process returned 1 (0x1) execution time : 0.094 s
Press any key to continue.

====================================================================================

#include<iostream>
int a,i;
int fun()
{
int b=1,c=2;
a=b+c;
return a;
}
i=fun()
首先,这里必须是传递a的副本
其次,为什么传递副本,不是由a的生命周期来定义的,比如a是否是全局,或者局部,甚至是static,都与是否传递副本没有关系的
最后,这里传递副本是取决于fun函数的,fun函数返回的类型是 int,也就是说返回值的传递时采用 ” 值传递 “,你应该懂这个名词,不是地址传递,而值传递,明显特征是要传递副本
换句话说,如果定义fun函数如下:
int& fun();
那么可以return a,不会有副本产生。注意必须是a为全局的情况下,否则会引起警告,禁止传递局部变量的引用,因为a的声明周期会马上结束掉。

???为什么不写成int& fun();这种形式呢?答案是没必要。int是内部自定义类型。对于自定义变量而言,引用与否引起的副本拷贝带来的工作量不是很大,相反,如果是自定义类型,不知道楼主学习了class没有,那么引用返回就非常有必要了。
因为带来的副本拷贝可能非常耗时,而这也是C++之父strup反复强调了,也是我们需要常常使用的
void   function(int   a) <-这里是传值调用,所以要建立一个参数的副本再传给函数 

这样一来a这个参数的原始数据就会保留,不会在函数中被改变: 

void   function(int   a)
{
a++;
}
这里如果a=1;函数执行完毕后a还是等于1. void function(int &a) <-这里是模拟一个指针,当编译器编译这个函数的时候,直接到a的地址去操作a,这样避免了产生一个副本可能带来的额外开销.但是增加了危险性 void function(int &a)
{
a++;
}
如果a的原始数据是1的话,那么a++后a的数据将变成2
不管a是全局变量还是局部变量

下面我们再看一种情况,这是返回引用给变量的情况:

#include <iostream>
#include <string>
using namespace std; float c;
float& test(float,float);
void main(int argc,char* argv[])
{
float pn=test(3.0f,1.2f);
cout<<pn;
cin.get();
} float &test(float a,float b)
{
c=a*b;
return c;
}
  这种返回引用给变量的情况下,在内存中,test()所在的栈空间内并没有产生临时变量,而是直接将全局变量c的值给了变量pn,这种方式是我们最为推荐的操作方式,因为不产生临时变量直接赋值的方式可以节省内存空间提高效率,程序的可读性也是比较好的。
#include <iostream>
#include <string>
using namespace std; float c;
float& test(float,float);
void main(int argc,char* argv[])
{
float &pn=test(3.0f,1.2f);
cout<<pn<<endl;
test(3.0f,1.2f)=12.1;//把函数作左值进行计算!
cout<<pn;
cin.get();
} float &test(float a,float b)
{
c=a*b;
return c;
}
  通常来说函数是不能作为左值,因为引用可以做为左值,所以返回引用的函数自然也就可以作为左值来计算了。   在上面的代码中: float &pn=test(3.0f,1.2f);   进行到这里的时候pn已经指向到了目标c的地址了。   接下来运行了 test(3.0f,1.2f)=12.1;   把函数作左值进行计算,这里由于test是返回引用的函数,其实返回值返回的地址就是c的地址,自然c的值就被修改成了12.1。

C/C++ ===复习==函数返回值问题(集合体==网络)的更多相关文章

  1. shell调用函数返回值深入分析

    编写shell脚本过程中,我们经常会自定义一些函数,并根据函数的返回值不同来执行相应的流程,那么我们如何来获取函数的返回值呢? 首先shell中调用函数有两种方式: 第一种:value=`functi ...

  2. Python从线程获取函数返回值

    Python中利用强大的threading模块可以很容易的实现多线程开发,提高运行速度.这一般是对某个进行大量计算操作的的函数进行多线程处理,然后合并各线程的结果.获取函数返回值的方法可以如下: 1) ...

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

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

  4. string类find函数返回值判定

     string类find函数返回值判定 代码示例 #include<iostream> #include<cstring> using namespace std; int m ...

  5. c语言main函数返回值、参数详解(返回值是必须的,0表示正常退出)

    C语言Main函数返回值 main函数的返回值,用于说明程序的退出状态.如果返回0,则代表程序正常退出:返回其它数字的含义则由系统决定.通常,返回非零代表程序异常退出. 很多人甚至市面上的一些书籍,都 ...

  6. Python学习教程(learning Python)--2.3.4Python函数返回值

    本节讨论Python函数返回值问题. Python和C语言一样,也可以在函数结束时返回一个值.但在定义自己的Python函数时,是不需要指定返回值数据类型的,这和Python不关心变量的数据类型是一致 ...

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

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

  8. Shell函数:Shell函数返回值、删除函数、在终端调用函数

    函数可以让我们将一个复杂功能划分成若干模块,让程序结构更加清晰,代码重复利用率更高.像其他编程语言一样,Shell 也支持函数.Shell 函数必须先定义后使用. Shell 函数的定义格式如下: f ...

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

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

随机推荐

  1. 使用纯 CSS 实现滚动阴影效果

    开门见山,有这样一种非常常见的情况,对于一些可滚动的元素而言.通常在滚动的时候会给垂直于滚动的一侧添加一个阴影,用于表明当前有元素被滚动给该滚出了可视区域,类似这样: 可以看到,在滚动的过程中,会出现 ...

  2. 多线程应用之调用start()方法和run()方法的区别

    今天在做项目的时候,遇到一个问题,两个一模一样的demo,运行出来的效果却一点也不一样,找了半天,就是有一行代码不同,一个是thread.start();一个是thread.run();和我预计的一样 ...

  3. 安卓mbn文件丢失,无法搜索移动信号,工程模式mbn乱改,不用QPST烧录怎样恢复?超简单!

    没有root,工程模式乱改mbn配置选项,导致mbn配置丢失,无法搜索移动网络. 重启若干次改配置都无效,清空网络设置无效,恢复出厂无效,recovery三清无效, 不太想拆机root麻烦,QPST配 ...

  4. 【小菜学网络】MAC地址详解

    上一小节介绍了以太网帧的结构,以及帧中各个字段的作用.参与以太网通讯的实体,由以太网地址唯一标识.以太网地址也叫做 MAC 地址,我们对它仍知之甚少. 以太网地址在不同场景,称谓也不一样,常用叫法包括 ...

  5. STM32 HAL库之串口详细篇

    一.基础认识 (一) 并行通信 原理:数据的各个位同时传输 优点:速度快 缺点:占用引脚资源多,通常工作时有多条数据线进行数据传输 8bit数据传输典型连接图: 传输的数据是二进制:11101010, ...

  6. c++ 参数传递与返回值详解(reference)

    pass by value or pass by reference? 我们知道,当函数在传递值的时候,会新建一个变量(没有名字)储存这个值 然后传递.降低程序运行的效率. 如果使用引用(refere ...

  7. 如何实现CentOS服务器的扩容??

    Linux的硬盘识别: 一般使用"fdisk -l"命令可以列出系统中当前连接的硬盘 设备和分区信息.新硬盘没有分区信息,则只显示硬盘大小信息. 1.关闭服务器加上新硬盘 2.启动 ...

  8. intellij idea2020将javaWeb项目打成war包并部署到阿里云服务器遇到java.lang. UnsupportedClass VersionError问题(已解决)

    首先将javaweb项目打包成war文件(有关如何打包参考 https://jingyan.baidu.com/article/20b68a88642829386cec62f7.html.https: ...

  9. 在JavaScript种遇到这样的错误如何解决XML 解析错误:格式不佳 位置:http:/... 行 27,列 32:

    相信很多人在开发的过程中都会遇到在js中解析xml文档的问题.有时候文档解析失败,但就是不知道怎么失败的,哪里格式不对.这里教大家一个方法来排查JavaScript解析xml文档格式出错的办法. 1. ...

  10. 【Oracle】Oracle中chr()的含义

    oracle中chr含义 CHR(10)和 CHR(13)--在oracle都为换行 chr(32)--表示空格 DECLARE v_a VARCHAR2(255); v_b VARCHAR2(255 ...