精华内容
下载资源
问答
  • 在上一节中我们讲到了形式参数和实际参数的定义,同时讲到了从实际参数传递给形式参数的过程中按值传递和按地址传递的不同。为了更好的说明按值传递和按地址传递的区别,我们把上节的程序做一些修正:在函数声明行...

    9dca1e43696239535d99dce323d0da86.png

    大家好,我们今日继续讲解VBA代码解决方案的第125讲内容:关键字ByVal和ByRef的作用。在上一节中我们讲到了形式参数和实际参数的定义,同时讲到了从实际参数传递给形式参数的过程中按值传递和按地址传递的不同。为了更好的说明按值传递和按地址传递的区别,我们把上节的程序做一些修正:在函数声明行去掉参数a前面的关键字ByVal,结果会怎样呢?代码如下:

    Sub MynzNumbers_1()

    Dim a As Integer, b As Integer, c As Integer

    a = 10

    b = 20

    c = 30

    MsgBox MyAverage_1(a, b, c) & " " & a & " " & b & " " & c

    End Sub

    Function MyAverage_1(a, ByVal b, ByVal c)

    a = a + 60

    MyAverage_1 = (a + b + c) / 3

    End Function

    df620009a1017ecedc6f700cc70dec08.png

    大家想想这时的结果该是怎么样呢?如下面的截图:

    bac3581b0c236ecc9974f50f9e39a15f.png

    函数的结果仍然相同,但是函数MsgBox显示的变量a的内容现在是70了。说明这时就改变了储存在变量a里的原始数值。

    上面的过程如何理解呢?

    ① 每个要传递给函数过程(或子程序)的变量,都可能在接收时改变数值,是否需要保护变量的原始数值是非常重要的。

    ② VBA有两个关键字,提供是否认可改变变量内容的允许——ByRef和 ByVal,但要注意VBA默认地按地址(关键字ByRef)给函数过程(或子程序)传递信息,引用函数被调用时,函数参数会按地址传递数据。因此,如果函数改变了参数值,原始的数值就被改变了。

    ③ 在上面的例子中,函数MyAverage_1声明参数a的前面去掉了关键字ByVal时,你就会得到按地址传递参数的结果。如果你想要函数过程 改变原始数值,你不必专门在参数前加关键字ByRef,因为,变量数值的传递默认就是ByRef。

    本节的最后我们再谈一下按值传递的过程是如何进行的,当你在参数名称前使用关键字ByVal时,这意味着VBA复制一份原始数据,然后将复制 值传递给函数,如果函数改变了参数的数值的话,原始数据依然不会变——只有复制值变化。这就是为什么函数MyAverage改变了变量a的数值,而它的原始值还保持不变了。

    如果你对上述过程还是不清楚,我再做一个更加形象的说明:

    ①按址传递时,实质上实际参数是把指针(地址)传递给形式参数了,这时指针指向的地址的值即是实际参数,此时形式参数与实际参数分别有一个指针,但同时指向同一个地址。

    ②按数值递时,实质上实参是把复制后的数值传递给形参了,这个时候实际参数和形式参数具有不同的指针,形式参数的指针指向的地址是复制后数值的地址指针,此时实际参数的指针没有发生改变。

    今日内容回向:

    1 按值传递和按地址传递的关键字是什么?

    2 如何理解两种传递过程中的指针不同?

    展开全文
  • 代码如下:/给三个整数从小到大排序并求和及其平均值//其中,三个待求整数及其排序的...class Class1 { //x,y,z是形参,按值传递 static void Sort(int x, int y, int z) { int temp=0; if(x>y) { temp=x; x
  • C#方法参数传递-引用参数ref关键字

    千次阅读 2010-11-22 15:06:00
    引用参数(Reference Parameter ) 格式:方法名称(ref 参数类型 参数名称[,ref 参数类型 参数名称]) ref 关键字使参数按引用传递。其效果是,当控制权传递回调用方法时,在方法中对参数的任何更改都...

    引用传递好比你把文件在网络上的地址告诉他人,他人通过网络访问你计算机的文件,他可以对文件进行修改并保存,此时,文件的内容就会发生变化。引用传递在方法调用之后,可以保留参数值的修改。要实现引用传递,C#通过ref关键字和out关键字来实现。

    引用参数(Reference Parameter )
    格式:方法名称(ref 参数类型 参数名称[,ref 参数类型 参数名称])

    ref 关键字使参数按引用传递。其效果是,当控制权传递回调用方法时,在方法中对参数的任何更改都将反映在该变量中。若要使用 ref 参数,则方法定义和调用方法都必须显式使用 ref 关键字。

    using System;
    class Program
    {
    static void Main(string[]args)
    {
        int num1 = 4;
        int num2 = 8;
        Console.WriteLine("交换之前的字符串顺序为{0}、{1}", num1, num2);
        Program obj = new Program(); //创建对象
        obj.Change(ref num1, ref num2); //调用交换方法
        Console.WriteLine("交换之后的字符串顺序为{0}、{1}", num1, num2);
        Console.ReadLine();

    }
    //交换数据的方法
    private void Change(ref int num1, ref int num2)
    {
        int temp;
        temp = num1;
        num1 = num2;
        num2 = temp;

    }
    }

    注意:使用引用传递时,在方法定义中使用ref关键字修饰参数,在方法调用中也必须使用ref关键字。而且必须在调用方法之前对传递的参数进行初始化。

    展开全文
  • 用Ref和Out关键字引用传递比较分析: 由上文《由String类型分析,所产生的对参数传递之惑的解答》 文,我们对类型和引用类型,在用以关键字Ref传参时,所产生的可以导致原变量实现改变的结果进行了原因分析。...

    用Ref和Out关键字的按引用传递比较分析:

         由上文《由String类型分析,所产生的对参数传递之惑的解答》 文,我们对值类型和引用类型,在用以关键字Ref传参时,所产生的可以导致原变量实现改变的结果进行了原因分析。然而用关键字Out的按引用传递(注:文中所说的"按引用传递",从英文翻译对号入座应为Ref,然而此处为了表示在传递时都传递的是参数的地址这一共性,故此处把按Ref关键字和按Out关键字传值,认为是按引用传递的两种方法。),在实现机理上可以达到和按Ref关键字传值完全相同的结果(这点从编译器所变异的代码是相同的这点得以验证!)。对此我们采用上文的测试环境,只对后台代码做适当修改,具体代码如下:

    //Description: 通过代码测试,比较Ref和Out关键字的按引用传递的区别

    //CopyRight: http://www.cnblogs.com/yangmingming

    //Notes: 环境是初始值为空的四个TextBox,前面的Lbel标签标示其作用
              
    //按钮标示调用函数,并通过TextBox值显示对比效果

    public partial class ParaDelivery : System.Web.UI.Page
    {
        
    protected void Page_Load(object sender, EventArgs e)
        {

        }
        
    protected void btnSubmit_Click(object sender, EventArgs e)
        {
            
    int i = 1;
            
    //int i;
            string str = "This is a String";
            
    //string str;
            txtItiValue.Text = i.ToString();
            txtRefValue.Text 
    = str;
      
            AddValueType(
    out   i);
            AddRefType(
    out  str);
            txtChangedIntValue.Text 
    = i.ToString();
            txtChangedRefValue.Text 
    = str;
        }

        
    //两个被调用函数
        private void AddValueType(out  int funi)
        {
            funi
    =2;
        }
        
    private void AddRefType(out  string funStr)
        {
            funStr 
    ="This is a changed String";
        }
    }

    然而触发按钮事件的现实结果却完全如按Ref关键字的按引用传递结果,如下图示:

     

    即按Out传值实现了和按Ref传值的效果。然而就细节来说,它们还是具有不同点的,具体概括如下:

    1.Out传递方法,可以在函数调用之前未赋值,而按Ref传值在函数调用之前必须要赋值的;

    2.目的性不同:Out传递方法,顾名思义,Out主要是为从函数获取值的(因为按引用传递方法可以实现原变量的改变!),进而赋予原变量的,这是主要目的。而按Ref则不是这个目的存在的(它有可能是在调用函数中作为"右值",而并不是为了被更新)。我想这也是设计者针对两种情况分而设定的吧,呵呵~

     

    用Params关键字传值:

         先看一演示示例。后台代码即环境布置见说明:

    //Description: 通过代码测试,说明Param关键字作用

    //CopyRight: http://www.cnblogs.com/yangmingming

    //Notes: 通过设置两个提交按钮——分别可以实现调用同一个函数,而同时其参数个数不同
    // 最后将结果反映在TextBox中

    public partial class ParamDelivery : System.Web.UI.Page
    {
        
    protected void Page_Load(object sender, EventArgs e)
        {

        }
        
    protected void btnSubmit1_Click(object sender, EventArgs e)
        {
            
    int i = 1, j = 2, k = 3;
            txtDisplaySum.Text 
    = AddParamSum(i, j, k).ToString();
        }
        
    protected void btnSubmit2_Click(object sender, EventArgs e)
        {
            
    int i = 1, j = 2, k = 3, l = 4, m = 5;
            txtDisplaySum.Text 
    = AddParamSum(i, j, k, l, m).ToString();
        }
        
    //公共调用函数,实现参数的相加功能
        private int AddParamSum(params int[] arrParam)
        {
            
    int sum = 0;
            
    for (int i = 0; i < arrParam.Length; i++)
            {
                sum 
    += i;
            }
            
    return sum;
        }
    }

    当分别触发按钮1(btnSubmit1)和按钮2(btnSubmit2),所产生结果见下图示:

     

     

    可见他们都实现了对各自参数的相加功能,这比使用重载的Add函数要简便的多(况且适应性更强了)。Params的实现机理即是通知编译器要将传递过来参数,包装成数组来处理。

    附:在使用Params时注意事项:

    1.Params所修饰的只能为一维数组;

    2.Params可以修饰任何类型,将函数中类型定义为 Object;

    3.在函数中,Params项必须置于最后位置;

     

    综述之,作为对参数传递的补充部分,这里比较了按Ref关键字和按Out关键字的按引用传递,以及C#所提供的对于不定项数组的"智能方法"——Params关键字使用。至此对参数传递相关知识又做了一次回顾,呵呵

     

     

     

    转载于:https://www.cnblogs.com/yangmingming/archive/2010/01/31/1660315.html

    展开全文
  • /给三个整数从小到大排序并求和及其平均值//其中,三个待求整数及其排序的结果由引用参数传递;其和由输出参数传递;平均值由返回值返回。//在Main()方法中实现三个待求整数...class Class1 { //x,y,z是形参,按值传递

    问题与解答:
    1,值传递时,为什么被调用的方法中的形参值的改变不会影响到相应的实参?
       答:因为按值传递时,系统首先为被调用的方法的形参分配内存空间,然后把实参中的值按位置一一对应“复制”给形参。形参中存储的值只是一份实参的拷贝,因此被调用方法中形参值的任何改变都不会影响到相应的形参。

    2,值传递和引用传递有什么不同,什么是值参数,它以什么方式传递?
       答:值传递时,系统首先为被调用方法的形参分配内存空间,并将实参的值按位置一一对应地复制给形参,此后,被调用方法中形参值得任何改变都不会影响到相应的实参; 而引用传递时,系统不是将实参本身的值复制后传递给形参,而是将其引用值(即地址值)传递给形参,因此,形参所引用的该地址上的变量与传递的实参相同,方法体内相应形参值得任何改变都将影响到作为引用传递的实参。

    3,什么是形参,什么是实参?
       答:

       形参:在定义函数中指定的参数就是形参,在未出现函数调用时,他们并不占内存中的存储单元,只有在发生函数调用时,函数中的形参才被分配内存单元。在调用结束后,形参所占的内存单元也被释放。
      
       实参:实参可以是常量、变量和表达式,但要求有确定的值。在调用时将实参的值赋给形参。在内存中,实参单元和形参单元是不同的单元。在调用函数时,给形参分配存储单元,并将实参对应的值传递给形参,调用结束后,形参单元被释放,实参单元仍保留原值。
      
       理解:
            实参就是送进去方法中的东西~~行参就是把送进来的东西在方法中进行拷贝加工,加工完后方法就返回一个东西--返回值。

            值传递的时候,实参是不变的~形参是随着计算而变化的~~ 
            指针/引用传递的时候~~行参怎么变~实参就怎么变....
            

    参数的传递分为:1.值方式参数传递,2.引用方式参数传递。
    1)按值传递(不能改变实参)

        实参是变量,表达式等数值。

        函数调用的时候,实参和形参存在于内存中2快不同的区域,实参先自己复制一份拷贝,再把拷贝传给形参。由于是传递的是拷贝,所以实参不会受形参的影响,实参值不会被改变。

    2)按地址传递(可以改变实参)

        实参是指针/引用。

        函数调用的时候,指针传给你,形参和实参指针都一样,对形参的任何操作就等于对实参的操做。实参的值就可以被改变。


    对参数的影响:
    2种数据类型:值类型+引用类型
    2种传参方式:值传参+引用传参(ref与out关键字);

    以上的四种参数的组合 除了值传参方式传递值类型数据,其他的组合方式对参数的操作都会影响参数,都会改变!

    值类型:简单类型(int,float,double,long,char,bool)+结构+枚举
    存储结构:数据存放在栈中(栈:先进后出;单入口,单出口);效率高
    赋值方式:传的是值

    引用类型:除去简单类型(int,float,double)+结构+枚举以外的类型都是引用数据类型。如string;object;类;数组;委托;接口...
    存储结构:栈中存地址;堆中放数据;
    赋值方式:传的是数据的地址。

     

    形参:全称为"形式参数"是在定义函数名和函数体的时候使用的参数,目的是用来接收调用该函数时传入的参数.
    实参:全称为"实际参数"是在调用时传递个该函数的参数.

    形参和实参的类型必须要一致,或者要符合隐含转换规则,
    当形参和实参不是指针类型时(即不是按引用传递,而是按值传递时),
    在该函数运行时,形参和实参是不同的变量,
    他们在内存中位于不同的位置,形参将实
    参的内容复制一份,在该函数运行结束的时候形参被释放,
    而实参内容不会改变.

    而如果函数的参数是指针类型变量(按引用传递),在调用该函数的过程
    中,传给函数的是实参的地址,在函数体内部使用的也是
    实参的地址,即使用的就是实参本身.所以在函数体内部
    可以改变实参的值.

    按引用传递最大的用途是实现“操作符”重载!

     

    ref参数与out参数的区别在于:ref参数在调用方法前必须几经初始化。而out参数在调用方法前可以没有初始化,他们都以引用传递方式传递


    C++有了“引用传递”后,“形参的改变不影响实参”被判无效。因为传递给函数的并不是一个值,而是变量自身。在函数中定义的形参虽然还是局部变量,但却是一个引用。虽然这个引用的作用域仅限于函数内部,但是由于它与实参就是同一回事,所以对它的操作完全等同于对实参的操作。比如你叫“黑旋风”去买鱼,或者叫“铁牛”去买鱼,去的都是同一个人。
      C++为什么要有“引用传递”这回事?一种说法是只有引用才能达到操作符重载的目的,这个以后再谈。但是,撇开这个不谈,形参是不是引用,直接影响了程序执行的效率。前面提到过,函数调用时要用实参的值去初始化形参,初始化的过程包含了定义一个变量、然后给它赋一个值两个过程,如果这个变量并不是内部变量,而是一个类对象,那么,定义一个类对象可能很复杂,而初始化这个对象一样会很复杂。而引用只是给对象取一个别名,不涉及定义与初始化,离开作用域时也不用释放。
      相比之下,用指针传递可以避免类对象的定义、初始化与释放。只需要付出指针变量的定义、初始化与释放的代价。但是,指针的杀伤力太大。即使是熟练的程序员,也不能保证绝不出现“野指针”,野针的代价几乎无一例外是程序崩溃。
      引用也不是吃素的,如果说指针传递是“帮你配了一把我家的钥匙”,那么引用传递就是直接把我家的财产都交给了你。有时,我们使用引用传递仅仅是为了效率,而不希望实参被修改,那就要记得把形参标记为const,如“UINT GetLength(const CString&)”。
      顺便说一句,指针传递也可以这样做。把形参定义为指向const对象的指针(而不是const指针),可以降低杀伤力,保护实参所对应的内存。如果是普通的值传递,那么有没有const对函数外部并不影响。但是,我个人认为,有时候加上const也是一件好事。如果程序的逻辑并不需要改变参数,而实际上误写了代码,加上const可以让编译器帮我们找出BUG。

    展开全文
  • 在上一节中我们讲到了形式参数和实际参数的定义,同时讲到了从实际参数传递给形式参数的过程中按值传递和按地址传递的不同。为了更好的说明按值传递和按地址传递的区别,我们把上节的程序做一些修正:在函数声明行...
  • 数据类型1.类型:int,char,double,bool等基本数据类型 2.引用类型:类,数组,接口,...可以用关键字ref,使类型参数按引用传递引用传递引用类型变量存储对象的内存地址,赋值会创建地址副本,指向同一对象,对
  • 参数使用ref、out、in修饰后,参数则会按引用传递,而非按值传递。 在使用ref、out、in关键字时,需要在方法定义和方法调用处显示的使用关键字。下面就来看一下实际的使用案例,示例如下: using System; ...
  • 如何用java语言实现C#中的ref关键字(按引用传递参数)的效果在上一篇文章中(Java的参数传递是值传递还是引用传递),主要分析了java语言的参数传递只有按值传递而没有按引用传递。那么java语言如何实现C#中ref关键字...
  • 在上一节中我们讲到了形式参数和实际参数的定义,同时讲到了从实际参数传递给形式参数的过程中按值传递和按地址传递的不同。为了更好的说明按值传递和按地址传递的区别,我们把上节的程序做一些修正:在函数声明行...
  • 向一个方法中传递参数,有两种类型,一种是按值传递,一种是按引用传递 按值传递时,方法对参数的改变不会影响原来变量的值 按引用传递时,方法对参数的改变会同时改变原有变量的值 ref和out关键字会强制将...
  • js高程里面有这么一句话 zhihu上面有人给出的比较好的解释,整理如下: ...2、将参数的地址复制一份,按值传递地址,即引用复制(reference-copy)传递 3、对于参数的完全引用传递(c# 中的 ref 关键字...
  • C# 参数关键字ref

    千次阅读 2013-01-29 13:43:02
    ref 关键字使方法引用传递,其效果是,当控制权传递给调用方法时,在方法中对参数所做的任何修改都会反映在改变量中。 示例如下: int i = 10; // 查看调用方法之前的 Console.WriteLine("Before the ...
  • 什么是按引用传递和按值传递? 1、值类型按引用传递,使用 ref 关键字参数结果会传递外层。 如: static void SetDefault(ref int s) { s=1; } static void Test() { int s=0; SetDefault(ref...
  • 1 位置参数 调用函数时根据函数定义的参数位置来传递参数, 并且参数的顺序必须一一对应,少或者多参数都不可以。 语法: ... # 调用的时候,具体参考的是位置,位置赋值 def hello_(n...
  • 参数传递

    2019-05-05 22:22:05
    参数传递前言参数传递种类ref修饰符Out修饰符可变参数 前言 不管是类型还是引用类型,你都可以使用ref或者out关键字 来实现参数的引用传递。并且在按照引用类型进行传递时候,方法 的定义和调用必须显式的使用...
  • python的参数传递机制具有值传递(int、float等值数据类型)和引用传递(以字典、列表等非值对象数据类型为代表)两种基本机制以及方便的关键字传递特性(直接使用函数的形参名指定实参的传递目标,如函数定义为def f(a,b...
  • 参数传递总结

    2019-08-06 14:27:49
    如果在声明过程时,形式叁数名前加上关键字“BYVal”表示在调用该过程时,该参数按值传递的,按值传递叁数方式下,在过程被调用时,传递给形参的是调用过程中的相应实参的值,形参与实参各占有不同位置的存储空间...
  • python 参数传递机制

    2019-03-03 08:34:09
    python的参数传递机制具有值传递(int、float等值数据类型)和引用传递(以字典、列表等非值对象数据类型为代表)两种基本机制以及方便的关键字传递特性(直接使用函数的形参名指定实参的传递目标,如函数定义为def ...
  • Java参数处理始终是“按值调用” (是的,即使在处理对象时也是如此),这是为什么。这是真的。当处理非原始数据类型时,Java处理对对象的引用。 对象本身不会从被调用者传递给目标函数! 而是传递一个...
  • c#中对于参数的传递,有二种处理方式,默认情况下:值类型的参数按值传递(即:方法体内的参数是原值的副本);引用类型的参数,"加ref关键字后“,按引用传递(即:方法体内的参数,是对象的指针引用,在方法体内...
  • 写了两个方法,一个是多关键字的快速排序,一个是基于多关键字的基速排序。两个方法的参数列表是一样一样的,但是快速排序正常工作,但是基数排序传出来的参数一点没有改变,苦思冥想了半天也没想通是怎么回事,于是...
  • c#中对于参数的传递,有二种处理方式,默认情况下:值类型的参数按值传递(即:方法体内的参数是原值的副本);引用类型的参数,"加ref关键字后“,按引用传递(即:方法体内的参数,是对象的指针引用,在方法体内...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 400
精华内容 160
关键字:

参数传递按值传递关键字