ByVal和ByRef的区别

原创 2005年04月25日 10:07:00

                                     

ByVal 传送参数内存的一个拷贝给被调用者。也就是说,栈中压入的直接就是所传的值。
ByRef 传送参数内存的实际地址给被调用者。也就是说,栈中压入的是实际内容的地址。被调用者可以直接更改该地址中的内容。
ByVal是传递值 源数据不会被修改
你可以把这个值当作自己的局部变量来使用
ByRef是传递地址 , 源数据可能被修改
你对这个变量的操作将对你传入的那个变量产生影响,就像指针的感觉
 
实例:
sub Add1(ByVal no as int32)
    no=no+100
end sub
sub Add2(ByRef no as int32)
    no=no+100
end sub
private sub button1_click(sender as object,e as eventargs)handles button1.click
    dim a as int32
    a=100
    Add1(a)
    msgbox ("a的值为:" & a)     '显示:a的值为100
    Add2(a)
    msgbox ("a的值为:" & a)     '显示:a的值为200,因为Add2中的参数no为ByRef,即
                                 '按地址传递,因此在Add2中对no进行修改后,将会导致
                                 '源参数a的值也被修改。
End Sub
——————————————————————————————————————
3、ByVal和ByRef
    ByVal传递的参数值,而ByRef传递的参数的地址。在这里,我们不用去区别传指针/传地址/传引用的不同,在VB里,它们根本就是一个东西的三种不同说法,即使VB的文档里也有地方在混用这些术语(但在C++里的确要区分指针和引用)
    初次接触上面的程序二SwapPtr的朋友,一定要搞清在里面的CopyMemory调用中,在什么地方要加ByVal,什么地方不加(不加ByVal就是使用VB缺省的ByRef)
    准确的理解传值和传地址(指针)的区别,是在VB里正确使用指针的基础。
    现在一个最简单的实验来看这个问题,如下面的程序三:
【程序三】:'体会ByVal和ByRef
    Sub TestCopyMemory()
        Dim k As Long
        k = 5
Note:   CopyMemory ByVal VarPtr(k), 40000, 4
        Debug.Print k
    End Sub
    上面标号Note处的语句的目的,是将k赋值为40000,等同于语句k=40000,你可以在"立即"窗口试验一下,会发现k的值的确成了40000。
    实际上上面这个语句,翻译成白话:
 -----------------------------------------------------------------
 就是从保存常数40000的临时变量处拷贝4个字节到变量k所在的内存中。
 -----------------------------------------------------------------
    现在我们来改变一个Note处的语句,若改成下面的语句:
Note2:   CopyMemory ByVal VarPtr(k), ByVal 40000, 4
    这句话的意思就成了,从地址40000拷贝4个字节到变量k所在的内存中。由于地址40000所在的内存我们无权访问,操作系统会给我们一个Access Violation内存越权访问错误,告诉我们"试图读取位置0x00009c40处内存时出错,该内存不能为'Read'"。
    我们再改成如下的语句看看。
Note3:   CopyMemory VarPtr(k), 40000, 4
    这句话的意思就成了,从保存常数40000的临时变量处拷贝4个字节到到保存变量k所在内存地址值的临时变量处。这不会出出内存越权访问错误,但k的值并没有变。
    我们可以把程序改改以更清楚的休现这种区别,如下面的程序四:
【程序四】:'看看我们的东西被拷贝到哪儿去了
    Sub TestCopyMemory()
        Dim i As Long, k As Long
        k = 5
        i = VarPtr(k)
NOTE4:  CopyMemory i, 40000, 4
        Debug.Print k
        Debug.Print i
        i = VarPtr(k)
NOTE5:  CopyMemory ByVal i, 40000, 4
        Debug.Print k
    End Sub
程序输出:
5
40000
40000
    由于NOTE4处使用缺省的ByRef,传递的是i的地址(也就是指向i的指针),所以常量40000拷贝到了变量i里,因此i的值成了40000,而k的值却没有变化。但是,在NOTE4前有:i=VarPtr(k),本意是要把i本身做为一个指针来使用。这时,我们必须如NOTE5那样用ByVal来传递指针i,由于i是指向变量k的指针,所以最后常量40000被拷贝了变量k里。

大学生如何让自己强大起来(计算机、电子方向)

请让我在此不害臊的标上原创,这样才能让篇文章传的更远。 由于没有经过作者的同意,不敢全文复制他的文章,标上转载。后来想通了,直接给一个连接,到他那里,不就解决了这个问题了嘛! 好文章,大家一起分享...
  • wolinxuebin
  • wolinxuebin
  • 2012年05月30日 13:00
  • 1370

VarPtr、StrPtr和ObjPtr函数的用法

发展历史在Basic语言演变成QBasic,然后到Visual Basic之前,VarPtr函数就已经存在了。开始,这个函数存在于VB运行库1.0版中。通过声明可以调用这个函数:Declare Fun...
  • yas
  • yas
  • 2005年10月28日 16:06
  • 1519

给初学者:用VB写外挂 ———— 从窗口到PID,进而读写内存

我们首先从HWND、PID入手,这是我们经常要用到的两种“标志符”。 HWND:窗口句柄,当我们要向游戏窗口发送一个按键或输入一段文本时,它将非常有用。PID:进程标志符,当我们要操作内存、截获和修改...
  • zcsor
  • zcsor
  • 2006年08月27日 22:07
  • 53145

vb 指针的操作

VB指针教程1 '先理解下变量的地址与指向这个地址的值。xx省xx市xx街xx号就是一个地址, '指向这个地址的值就是这个地址就有什么。比如这个地址是张三家的地址, '张三的家有什么呢?...
  • tangyanzhi1111
  • tangyanzhi1111
  • 2016年08月10日 16:37
  • 775

byval 和byref的区别,今天刚明白。

以前看一本书上,写着VB的两种参数传递方式:byval 和byrefbyval叫做“传值”,想当于把值复制一份到新的变量中。而byref叫做传址,相当于把原变量的地址传过去。不过今天我发现,byref...
  • super852
  • super852
  • 2005年01月23日 23:20
  • 958

VB中ByVal和ByRef

这是vb中传值与传址的参数修饰 byval 是按值传送,在传的过程中不会改变原来的值,仅仅传送的是一个副本,而 byref 相反,从内存地址来说,后者是同一个内存地址ByVal为传值,当你把函数外的一...
  • ninjya_luck
  • ninjya_luck
  • 2008年04月23日 13:09
  • 6162

VB 从零开始编外挂(完整实践版)

用管了别人 的外挂确实不爽,有没想过自己写个外挂玩玩??OK ,LIST’ GOVB 从零开始编外挂(一) ----------------------------------------------...
  • lzlyh
  • lzlyh
  • 2007年06月27日 20:27
  • 1085

菜鸟写游戏外挂

偶与同学玩游戏时,不仅想起作弊,是可以让我所做的操作更少呢?或者改掉程序里的数据呢?就这样我开始写这个的一个程序。向程序发消息,从程序得到消息,然后在程序内存空间找我要的数据,然后再更改。在Windo...
  • yin138
  • yin138
  • 2006年10月12日 15:42
  • 1798

数据搬运工-VB中参数(ByVal,ByRef)的传递

在作品展中纠结过,到现在的学生信息管理系统,每一次使用ByVal和ByRef都让我如入云里雾里,而它们却是数据传递的关键,只有彻底理解了它们,我们的程序代码才能够在传递的过程中避免很多逻辑和意想不到的...
  • wlccomeon
  • wlccomeon
  • 2012年08月28日 16:58
  • 5492

Byval 和 Byref的区别

在VB中,提高过程和和函数,一定少不了参数,参数传递时过程中非常重要的问题。通过实际参数和形式参数的传递可以实现调用过程和被调用过程之间的信息交换。在这里首先要明白实参和形参。举个例子吧: 假设定义一...
  • zjx86320
  • zjx86320
  • 2013年07月22日 21:25
  • 1163
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:ByVal和ByRef的区别
举报原因:
原因补充:

(最多只允许输入30个字)