函数的参数传递定义:在调用一个函数时,将实参传递给形参。

  C++中函数的参数传递有按值传递、地址传递和引用传递3种方式。注意:地址也是一种值,按值传递和按地址传递都是单向的值传递方式,即形参都不会回传给实参。但是由于地址的特殊性,地址传递可以间接地改变实参的值,所以分开讨论。

一、按值传递

函数本身不对实参进行操作。

    #include<iostream>
using namespace std;
void swap(int,int);//函数声明 void main() {   int a=,b=;   swap(a,b);//调用时,形参x、y重新申请了空间,把a、b值拷贝到形参,不对实参产生影响   cout<<"a = "<<a<<",b = "<<b<<endl; }  void swap(int x,int y)//函数定义 {    int temp = x;     x = y;     y = temp;   } 执行结果如下:
a = ,b =

二、地址传递

所谓地址传递,是指在函数定义时将形参生命成指针,这样调用函数时就需要指定地址形式的实参。

    #include<iostream>
using namespace std;
void swap(int *,int *);//函数声明 void main() {   int a=,b=;   swap(&a,&b);//swap中不是交换了x和y的值,而是交换了两个指针指向的两个地址处的值;因为同一地址的数据值是相同的,从而间接地达到了回传参数的目的   cout<<"a = "<<a<<",b = "<<b<<endl; }  void swap(int *x,int *y)//函数定义 {    int temp = *x;//"*"符号表示取指针指向的值     *x = *y;     *y = temp;   } 执行结果如下:
a = ,b =

三、引用传递

c++中变量名对应着内存的存储位置,可以使用一个特定的内存地址访问到它,引用则引入了变量的另一个名字(别名),它和这个变量有同一内存地址,对应用的操作,也就是对被它引用的变量的操作。

    #include<iostream>
using namespace std;
void swap(int &,int &);//函数声明 void main() {   int a=,b=;   swap(&a,&b);//将实参的地址放入C++为形参分配的内存空间中   cout<<"a = "<<a<<",b = "<<b<<endl; }  void swap(int &x,int &y)//函数定义 {    int temp = x;//引用使用的时候,直接当变量名用     x = y;     y = temp;   } 执行结果如下:
a = ,b =

  Java中,swap函数什么时候使用,由于何种必要使用?

在类中,实现两个成员变量值交换的swap方法:

 class Test

 {

   private int a;

   private int b;

   //swap函数没有使用形参的必要性,本身就可以直接操作内成员a,b,不存在参数拷贝,a,b值交换成功

   public void swap()

   {

     int temp = this.a;

     this.a = b;

     this.b = temp;

   }  

 }

交互一个数组中的两个元素的值(可以画内存图分析,“栈中一小块内存指向堆中一大块内存,每new一次,就有新的指向”,如 Node ns[] = new Node[3]; ns[0] = new Node(0);)

public static void main(String []args)
{
int a[] = {1,2};
int temp = a[0];
a[0] = a[1];
a[1] = temp;
System.out.println("a[0] = " + a[0] + ",a[1] = " + a[1]);
}
打印结果:
a[0] = 2,a[1] = 1
    public void changeRefNode()
{
Node nodes[] = new Node[2];
nodes[0] = new Node(0);
nodes[1] = new Node(1);
Node temp = nodes[0];
nodes[0] = nodes[1];
nodes[1] = temp;
System.out.println(nodes[0].n + " " + nodes[1].n);
//打印:1 0,交换成功 }

两个数组交换值

    public static void main(String args[])
{
int a[] = {1,2};
int b[] = {3,4};
int temp[] = a;
a = b;
b = temp;
for(int i=0;i<a.length;i++)
{
System.out.print("a[" + i + "]=" + a[i] + " ");
}
System.out.println();
for(int j=0;j<b.length;j++)
{
System.out.print("b[" + j + "]=" +b[j] + " ");
}
}
打印结果:
a[0]=3 a[1]=4
b[0]=1 b[1]=2

对于引用数据类型

public class ReferValue
{
static String ss = "hello"; public static void change(String str)
{
str = "world";//调用change函数时,传ReferValue.ss,不能改变成员ss值。
    // ss = "ss changed";//直接反问修改,可以改变ss值

   } 
  public static void main(String args[])
  {
    change(ReferValue.ss);//将类或者对象的成员变量,“暴露出来”,当成实参传递给形参,这种做法就有待商榷。
  }
}

  附Java官方文档对于函数参数传递的解释(出自:http://docs.oracle.com/javase/tutorial/java/javaOO/arguments.html):

Passing Information to a Method or a Constructor

Passing Primitive Data Type Arguments

Primitive arguments, such as an int or a double, are passed into methods by value. This means that any changes to the values of the parameters exist only within the scope of the method. When the method returns, the parameters are gone and any changes to them are lost. Here is an example:

public class PassPrimitiveByValue {

    public static void main(String[] args) {

        int x = 3;

        // invoke passMethod() with
// x as argument
passMethod(x); // print x to see if its
// value has changed
System.out.println("After invoking passMethod, x = " + x); } // change parameter in passMethod()
public static void passMethod(int p) {
p = 10;
}
}

When you run this program, the output is:

After invoking passMethod, x = 3

Passing Reference Data Type Arguments

Reference data type parameters, such as objects, are also passed into methods by value. This means that when the method returns, the passed-in reference still references the same object as before.However, the values of the object's fields can be changed in the method, if they have the proper access level.

For example, consider a method in an arbitrary class that moves Circle objects:

public void moveCircle(Circle circle, int deltaX, int deltaY) {
// code to move origin of circle to x+deltaX, y+deltaY
circle.setX(circle.getX() + deltaX);
circle.setY(circle.getY() + deltaY);//会修改myCircle的成员变量y的值;通过set方法 // code to assign a new reference to circle
circle = new Circle(0, 0);//不会修改引用myCircle的指向
}

Let the method be invoked with these arguments:

moveCircle(myCircle, 23, 56)
  Inside the method, circle initially refers to myCircle.

  The method changes the x and y coordinates of the object that circle references (i.e., myCircle) by 23 and 56, respectively. These changes will persist when the method returns.

  Then circle is assigned a reference to a new Circle object with x = y = 0.    (circle = new Circle(0, 0);)   This reassignment has no permanence, however, because the reference was passed in by value and cannot change. Within the method, the object pointed to by circle has changed, but, when the method returns, myCircle still references the same Circle object as before the method was called.

由swap引发的关于按值传递和引用传递的思考与总结的更多相关文章

  1. PHP中按值传递和引用传递的区别

    有次跟朋友讨论对象传值的方式时提到引用传值时,在大脑中搜索五秒钟,果断确定在这两个项目当中并没有用到.今天去问了一下度娘,顺便做了个小测试: 按值传递: 引用传递: 按值传递中原来参数的值在调用其他函 ...

  2. 【转】java方法参数传递方式--按值传递、引用传递

    java的方法参数传递方式有两种,按值传递和引用传递 1.按值传递 参数类型是int,long等基本数据类型(八大基本数据类型),参数传递的过程采用值拷贝的方式 代码片段1: public class ...

  3. **JAVA参数传递方式 (按值传递与引用传递区别)

    https://blog.csdn.net/q5706503/article/details/82910428public class TestMain { public static void ma ...

  4. python对象的复制问题,按值传递?引用传递?

    这部分这篇博文说的很明白,转了过来 作者:winterTTr (转载请注明)http://blog.csdn.net/winterttr/article/details/2590741#0-tsina ...

  5. Java语言对对象采用的是引用传递还是按值传递?

    按值调用表示方法接收的是调用者提供的值:而按引用调用表示方法接收的是调用者提供的变量地址:一个方法可以修改传递引用所对应的变量值, 而不能修改传递值调用所对应的变量值: Java语言对对象采用的是引用 ...

  6. 【C#】无损转换Image为Icon 【C#】组件发布:MessageTip,轻快型消息提示窗 【C#】给无窗口的进程发送消息 【手记】WebBrowser响应页面中的blank开新窗口及window.close关闭本窗体 【手记】调用Process.EnterDebugMode引发异常:并非所有引用的特权或组都分配给呼叫方 【C#】DataRowState演变备忘

    [C#]无损转换Image为Icon 如题,市面上常见的方法是: var handle = bmp.GetHicon(); //得到图标句柄 return Icon.FromHandle(handle ...

  7. 一个随意list引发的惨案(java到底是值传递还是引用 传递?)

    前两天写了一个递归,因为太年轻,把一个递归方法需要用到的list定义该递归方法外了,结果开始断点测试的时候有点小问题 ,然后上线之后因为数据量太多导致了一个java.util.ConcurrentMo ...

  8. 值传递:pass by value(按值传递) 和 pass by reference(引用传递)-[all]-[编程原理]

    所有的编程语言,都会讨论值传递问题. 通过一个js示例直观认识 //理解按值传递(pass by value)和按引用传递(pass by reference) //pass by value var ...

  9. 124、Java面向对象之引用传递实例二,String类型按值传递

    01.代码如下: package TIANPAN; /** * 此处为文档注释 * * @author 田攀 微信382477247 */ public class TestDemo { public ...

随机推荐

  1. 【代码审计】XYHCMS V3.5任意文件下载漏洞分析

      0x00 环境准备 XYHCMS官网:http://www.xyhcms.com/ 网站源码版本:XYHCMS V3.5(2017-12-04 更新) 程序源码下载:http://www.xyhc ...

  2. ValueError: {0} is not a valid coordinate or range问题解决

    获取excel多列方法: >>> colC = ws['C'] >>> col_range = ws['C:D'] 采用python 实现时,开始列与结束列采用变量 ...

  3. 浅谈webpack4.0 性能优化(转)

    前言:在现实项目中,我们可能很少需要从头开始去配置一个webpack 项目,特别是webpack4.0发布以后,零配置启动一个项目成为一种标配.正因为零配置的webpack对项目本身提供的“打包”和“ ...

  4. QT textBrowser 使用

    使用环境: VS2010 & QT Designer5 1. 在QT Designer 拖入  textBrowser,点击右键属性获得 name值 2. 在程序使用的地方 加入  ui.te ...

  5. I - 取石子游戏

    有两堆石子,数量任意,可以不同.游戏开始由两个人轮流取石子.游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子:二是可以在两堆中同时取走相同数量的石子.最后把石子全部取完者为胜者. ...

  6. Saltstack设置安装源为阿里源

    Saltstack设置安装源为官方源有时候在国内网络不好安装较慢或者安装不上,可设置为阿里源 比如对于 Centos 7 系统,在 saltstack 的官网提供的配置初始化手册是: sudo yum ...

  7. 用C# 7.0的switch...case模式匹配取代一堆if语句

    今天在重构代码时对下面的一堆if语句实在看着不顺眼. if(activation == null) { _logger.LogError("x1"); return Boolean ...

  8. [No000018B]写代码要用 Vim,因为越难入门的工具回报越大

    编者按:现在的技术界有一种倾向,将软件/应用操作简单化,用户能轻松上手.但是工具是否强大,取决于它能否灵活地满足使用者的各种需要.有些工具虽然很难入门,学会了便能对自己的操作有更深的层次的了解,能赋予 ...

  9. DHCP协议和PXE

    在学习IP地址基本概念之后,需要了解到如果需要和其他机器通讯,我们就需要一个通讯地址,我们需要给网卡配置一个地址. 如何配置 IP 地址? 可以用命令行自己配置一个地址.可以使用 ifconfig,也 ...

  10. 解决eclipse在线安装不了genymotion

    解决eclipse在线安装不了genymotion 2015-8-2阅读161 评论0 今天在网上看见网友说genymotion安卓模拟器是多麽的流畅,比起google自带的那些emulator快十倍 ...