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

博客介绍了VB的两种参数传递方式,byval传值是复制值到新变量,byref传址是传递原变量地址,且byref相当于C++中的引用。还指出C++有三种参数传递方式,VB有两种,同时说明了VB6和VB.NET默认的参数传递方式。
以前看一本书上,写着VB的两种参数传递方式:byval 和byref byval叫做“传值”,想当于把值复制一份到新的变量中。 而byref叫做传址,相当于把原变量的地址传过去。 不过今天我发现,byref的传址,其实并非相当于C++中的指针传址,而是相当于C++中的引用。 也就是说,在C++中,传递参数,有三种方式: void abc (int a){} void abc (int* a){} void abc (int& a){} 而在VB中,有两种: sub abc(byval a as integer) '想当于 void abc (int a){} sub abc(byref a as integer) '想当于 void abc (int & a){} 在VB6中,如果不写byval或byref,默认为byref,在VB.NET中,默认为byval
在 **VB6(Visual Basic 6.0)** **VBA(Excel/Office 宏语言)** 中,`ByVal` `ByRef` 是用来指定 **函数或子过程参数传递方式** 的关键字。它们决定了当调用一个函数时,参数是如何被传入的 —— 是传递值本身,还是传递对原始变量的引用。 --- ### ✅ 简明定义 | 关键字 | 含义 | 英文全称 | |--------|------|-----------| | `ByVal` | 按值传递(复制一份数据) | By Value | | `ByRef` | 按引用传递(直接操作原变量) | By Reference | --- ## 🔍 详细解释与代码示例 ### 1. `ByVal`:按值传递 - 调用函数时,系统会创建该参数的一个**副本**。 - 函数内部对该参数的任何修改,**不会影响原始变量**。 - 安全性高,适合不希望被篡改原始数据的情况。 #### 示例代码: ```vb Sub TestByVal() Dim x As Integer x = 100 Call ModifyValueByVal(x) MsgBox x ' 显示 100 —— 原值未变! End Sub Sub ModifyValueByVal(ByVal num As Integer) num = num * 2 End Sub ``` > 💡 尽管 `num` 在 `ModifyValueByVal` 中变成了 200,但因为是“按值”传入的副本,所以外面的 `x` 仍然是 100。 --- ### 2. `ByRef`:按引用传递(默认) - 参数传递的是原始变量的“内存地址”或“引用”。 - 函数内部可以直接修改原始变量的值。 - 效率更高(尤其是大对象、字符串),但风险也更高(可能意外修改)。 #### 示例代码: ```vb Sub TestByRef() Dim x As Integer x = 100 Call ModifyValueByRef(x) MsgBox x ' 显示 200 —— 原值被改变了! End Sub Sub ModifyValueByRef(ByRef num As Integer) num = num * 2 End Sub ``` > 💡 因为使用了 `ByRef`,函数内对 `num` 的修改直接影响了外部的 `x`。 --- ### 📌 默认行为:如果不写,默认是 `ByRef` 在 VB6/VBA 中,如果你没有显式写出 `ByVal` 或 `ByRef`,默认就是 `ByRef`! ```vb Sub Example(data As String) ' 等价于 ByRef data As String data = "changed" End Sub ``` 上面这行等同于: ```vb Sub Example(ByRef data As String) ``` 所以要特别小心! --- ### 🧪 字符串对象的特殊说明 虽然字符串不是数值类型,但在 VB 中也是可以被 `ByRef` 修改的(只要传引用): ```vb Sub ChangeString() Dim s As String s = "Hello" Call AppendText(s) Debug.Print s ' 输出 "Hello World" —— 成功修改! End Sub Sub AppendText(ByRef text As String) text = text & " World" End Sub ``` 但如果用 `ByVal`,就不能改变原字符串。 --- ### ⚖️ 使用建议对比表 | 特性 | `ByVal` | `ByRef` | |------|--------|---------| | 是否修改原变量 | ❌ 不会 | ✅ 会 | | 内存使用 | 多(复制) | 少(共享) | | 执行效率 | 较低(复制开销) | 高 | | 安全性 | 高(保护原数据) | 低(易误改) | | 默认? | 否 | ✅ 是 | --- ### ✅ 最佳实践建议 1. **如果不想让函数修改你的变量 → 使用 `ByVal`** ```vb Sub ProcessData(ByVal userName As String, ByVal id As Long) ``` 2. **如果你想通过函数返回多个值 → 使用 `ByRef`** ```vb Sub GetDimensions(ByRef width As Single, ByRef height As Single) width = 800 height = 600 End Sub ``` 这样就实现了“多返回值”。 3. **始终显式声明 `ByVal` 或 `ByRef`,避免依赖默认行为** --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值