vb6.0中按byval方式传递一个变量的地址与按byref传递这个变量本身等效吗?为什么?

解决方案 »

  1.   

    等效与否这个的具体问题具体分析
    就两者而言,含义是不同的,Byval是传值,也就是传递变量的一个副本;而Byref是传引用,也就是把地址传过去。
      

  2.   

    最好能分别讨论这个变量为long类型和string类型时的情况
      

  3.   

    假设这个变量叫X,是long类型
    ①byval x 时,vb会自动创建X的替身x1,然后将x1的地址返回给实参(完成外部变量与函数内部变量的对接,类似“索引”),函数对实参的操作实际是对x1的操作,x本身没有变化。
    ②byref x 时,vb会直接将x的地址返回给实参,函数对实参的操作实际是对x本身的操作。请问上面两条推论成立吗?
      

  4.   

    vb6.0中按byval方式传递一个变量的地址:错误,传递是值
    按byref传递才是变量的地址函数或过程的参数传递需要通过栈,栈是函数调用者和函数内部能够知道的内存地址,是一种调用约定,调用者和被调用者能够准确的理解每个栈内存属于哪个变量。
    调用的时候,ByVal则将对应的参数值复制到某个栈内存;ByRef的时候,则将该变量的地址复制到栈内存
      

  5.   

    以下摘自MSDN
    Byval
    按值
    一种将参数值而不是将地址传递给过程的方式,这就使过程访问到变量的复本。结果,过程不可改变变量的真正值。
    Byref
    按地址
    一种将参数地址而不是将值传递给过程的方式,这就使过程访问到实际的变量。结果,过程可改变变量的真正值。除非另作说明,否则按地址传递参数。
      

  6.   

    worldy
    我们的理解似乎有些误差。我的意思是
    vb6.0中按byval方式传递一个“变量的地址”
    “变量的地址”本身也是一个变量(可以想成是一个临时变量)假设为a,a代表了那个变量的地址,可以用取地址函数取到值赋值给a。
      

  7.   

    worldy你好“函数或过程的参数传递需要通过栈...”
    是怎么理解的,能不能分享下
      

  8.   

    等不等效,没那么简单!看你怎么用了。比如:在ActiveX DLL中,如果DLL有一个参数声明成ByRef,则这个参数是可以返回值给调用DLL的主程序的;如果这个参数声明成ByVal,则不能返回值给主程序。
    API函数VarPtr是返回变量的地址,为了获取字符串的指针,而非保存字符串的变量的指针,只须在变量名前加上ByVal即可:VarPtr(ByVal S)(相当于StrPtr(S),但不等于VarPtr(S))。
    举个例子:
    Dim S As String
    S = "CSDN"
    Debug.Print VarPtr(S), VarPtr(ByVal S), StrPtr(S) '在我的电脑里面结果分别为1307680、1847644、1847644这里有个详细例子,看完之后就明白了:http://topic.csdn.net/u/20090901/09/dddf35aa-7838-4415-85b2-222358422d81.html
      

  9.   


    你的意思是以Byval方式来传递一个地址,比如通过VarPtr获得地址传递?如果是这样
    VB的自定义函数肯定不等效,因为被调用者(函数或过程)在编译的时候,是按照定义时候按值或者按地址编译的,调用者如果使用ByVal 或者Byref修改调用的参数,对于内部函数将会出现编译错误。API调用,byval的声明参数,一般是不可以使用Byref进行强制
    但是Byref声明的参数,在一些时候可以使用ByVal进行强制,比如你先获得Varptr不知道说的对不对
      

  10.   

    说了一堆... 
    都什么啊.......对lz问题的回答: 等效 ...因为vb这种高级语言,掩盖的东西太多了,导致看起来似乎不一样,其实是一样的
    按照lz说的方法传过去后,参数都是一样的值, 只不过必须通过特殊方法来证明,比如 byval 的直接 msgbox 参数, byref的 copymemory a,参数,4 然后再 msgbox a
    如果相等就说明等效了, 其实根本就是等效的, 上面那些说了一堆的都没用, 只会让人越看越迷糊
      

  11.   

    PctGL
    可不可以说的再详细点
      

  12.   

    PctGL
    copymemory的第二个参数(设为变量b),copymemory函数内部用到的是b的内存地址,而不是b的值,是吗?感觉这里面被VB代劳的工作特别多,认识比较吃力
      

  13.   

    PctGL
    设:
    一个Long型变量为A,其内存地址ad=108,其va=1008。
    那么:
    任何一个使用他作为参数的函数(如:msgbox、copymenory...),无非使用以下两种方式传参。
    ①byval方式②byref方式
    例01:msgbox byref A
         msgbox byval A.ad
    例02:copymemory x,byref A,4
         copymemory x,byval A.ad,4
    例...
    我的问题是:这两种方式执行的结果相同吗?为什么?
      

  14.   

    弄的跟说书是的...模块里面写这些东西:private 变量1 as longsub TestByval(byval a as long)
      msgbox a
    end subsub TestByref( a as long)
      
       dim m as long 
       copymemory m,a,4
       msgbox m
    end sub
    调用:
    testbyval varptr(变量1)
    testbyref 变量1
      

  15.   

    改个Sub TestByref(a As Long)
      
      Dim m As Long
      copymemory m, VarPtr(a), 4
      MsgBox m
    End Sub
      

  16.   

    pctgl
    你把问题复杂了,而且你的命题和我想要的结论,推论关系不明确
      

  17.   

    ①函数相同,分别代入以下参数
    byref A
    byval A.ad
    ②结果相同则证明成立,否则就不对
    ③为什么?
      

  18.   

    真正理解透这个问题必须:
    VC调试(TC或BC用TD调试)时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
    对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。
    (Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
    想要从本质上理解C指针,必须学习汇编以及C和汇编的对应关系。
    从汇编的角度理解和学习C语言的指针,原本看似复杂的东西就会变得非常简单!
    指针即地址。“地址又是啥?”“只能从汇编语言和计算机组成原理的角度去解释了。”提醒:
    “学习用汇编语言写程序”

    “VC调试(TC或BC用TD调试)时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
    (Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
    想要从本质上理解C指针,必须学习C和汇编的对应关系。”
    不是一回事!不要迷信书、考题、老师、回帖;
    要迷信CPU、编译器、调试器、运行结果。
    并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。
    任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实!
      

  19.   

    问题最新思考
    前提:
    一个完整变量包含两方面内容①内存地址②值。
    假设有这样一个变量A,其内存地址为A.adr,其值为A.val
    那么当A作为参数传递进一个函数时可采用哪些方式?
    答:byref[vb默认方式]、byval
    具体思考见图:
      

  20.   

    “vb6.0中按byval方式传递一个变量的地址与按byref传递这个变量本身等效吗?为什么?” 
     
    byval、byref代表两种参数传递方式,本身不是函数,无法决定传递好的参数做什么用。参数的作用是由过程中的代码来决定的。如果把参数比作一块毛巾,如果我用它来洗脸就是脸布,用它来擦桌子就是抹布,要看过程是怎样使用它的,所以以上问题可以回答是等效的,也可以回答是不等效的,原因不在byval与byref,而在于我们在写这个过程代码时,是想怎样驾驭他们为我所用的。