传址与传值的问题

zky0901 2008-03-08 11:17:19
做了个例子
Module module1
Sub aa(ByRef p() As Integer, ByVal q() As Integer, ByRef s() As Integer, ByVal t() As Integer)
Dim i As Integer
Console.WriteLine("传递进过程的数组值")
Console.Write("P:")
For i = 0 To UBound(p)
Console.Write(CStr(p(i)) + " ")
Next
Console.WriteLine()
Console.Write("Q:")
For i = 0 To UBound(q)
Console.Write(CStr(q(i)) + " ")
Next
Console.WriteLine()
Console.Write("S:")
For i = 0 To UBound(s)
Console.Write(CStr(s(i)) + " ")
Next
Console.WriteLine()
Console.Write("T:")
For i = 0 To UBound(t)
Console.Write(CStr(t(i)) + " ")
Next
Console.WriteLine()

For i = 0 To UBound(p)
p(i) = p(i) + i ^ 3
Next
For i = 0 To UBound(q)
q(i) = q(i) + i ^ 3
Next
For i = 0 To UBound(s)
s(i) = s(i) + i ^ 3
Next
For i = 0 To UBound(t)
t(i) = t(i) + i ^ 3
Next
Console.WriteLine("运行后数组值")
Console.Write("P:")
For i = 0 To UBound(p)
Console.Write(CStr(p(i)) + " ")
Next
Console.WriteLine()
Console.Write("Q:")
For i = 0 To UBound(q)
Console.Write(CStr(q(i)) + " ")
Next
Console.WriteLine()
Console.Write("S:")
For i = 0 To UBound(s)
Console.Write(CStr(s(i)) + " ")
Next
Console.WriteLine()
Console.Write("T:")
For i = 0 To UBound(t)
Console.Write(CStr(t(i)) + " ")
Next
Console.WriteLine()
End Sub
Sub main()
Dim x() As Integer = {10, 10, 10}
Dim y() As Integer = {10, 10, 10}
Dim m() As Integer = {10, 10, 10}
Dim n() As Integer = {10, 10, 10}
Dim i As Integer
Console.WriteLine("原始数组值")
Console.Write("X:")
For i = 0 To UBound(x)
Console.Write(CStr(x(i)) + " ")
Next
Console.WriteLine()
Console.Write("Y:")
For i = 0 To UBound(y)
Console.Write(CStr(y(i)) + " ")
Next
Console.WriteLine()
Console.Write("M:")
For i = 0 To UBound(m)
Console.Write(CStr(m(i)) + " ")
Next
Console.WriteLine()
Console.Write("N:")
For i = 0 To UBound(n)
Console.Write(CStr(n(i)) + " ")
Next
Console.WriteLine()

Call aa(x, y, m, n)
Console.WriteLine("运行后的数组值")
Console.Write("X:")
For i = 0 To UBound(x)
Console.Write(CStr(x(i)) + " ")
Next
Console.WriteLine()
Console.Write("Y:")
For i = 0 To UBound(y)
Console.Write(CStr(y(i)) + " ")
Next
Console.WriteLine()
Console.Write("M:")
For i = 0 To UBound(m)
Console.Write(CStr(m(i)) + " ")
Next
Console.WriteLine()
Console.Write("N:")
For i = 0 To UBound(n)
Console.Write(CStr(n(i)) + " ")
Next
Console.WriteLine()
Console.ReadLine()
End Sub
End Module

得到的答案是
原始数组值
X:10 10 10
Y:10 10 10
M:10 10 10
N:10 10 10
传递进过程的数组值
P:10 10 10
Q:10 10 10
S:10 10 10
T:10 10 10
运行后数组值
P:10 11 18
Q:10 11 18
S:10 11 18
T:10 11 18
运行后的数组值
X:10 11 18
Y:10 11 18 //本人疑问:此处是传值的,应该还原成Y:10 10 10,为什么数值却被保留下来了
M:10 11 18
N:10 11 18 //本人疑问:此处是传值的,应该还原成N:10 10 10,为什么数值却被保留下来了

请各位帮小弟被惑啊



...全文
188 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
herol 2008-03-10
  • 打赏
  • 举报
回复
因为数组是引用类型的
调用时可以用这个
Call aa(x, (y), m, (n))
Cauly123 2008-03-09
  • 打赏
  • 举报
回复
在vb.net里 址类型byval还是传址
比如function abc(byval s as string)
s = ""
return s
end function
s就变成了""
当然数组也是这样了
清晨曦月 元老 2008-03-09
  • 打赏
  • 举报
回复
我不同意楼上的观点.
我用的是2005,,测试以下代码:
Public Class Form1

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim i As Integer = 1, d As Double = 1D, s As String = "s", a As Integer() = New Integer() {1, 2, 3}, al As New ArrayList
al.Add("0")
al.Add(1)
Debug.Print("=====================================")
Debug.Print("i = " & i)
Debug.Print("d = " & d)
Debug.Print("s = " & s)
For j As Integer = 0 To a.Length - 1
Debug.Print("a[" & j & "] = " & a(j))
Next
For j As Integer = 0 To al.Count - 1
Debug.Print("al[" & j & "] = " & a(j))
Next
Debug.Print("=====================================")
[Set](i, d, s, a, al)
Debug.Print("=====================================")
Debug.Print("i = " & i)
Debug.Print("d = " & d)
Debug.Print("s = " & s)
For j As Integer = 0 To a.Length - 1
Debug.Print("a[" & j & "] = " & a(j))
Next
For j As Integer = 0 To al.Count - 1
Debug.Print("al[" & j & "] = " & a(j))
Next
Debug.Print("=====================================")
End Sub
Sub [Set](ByVal i As Integer, ByVal d As Double, ByVal s As String, ByVal a As Integer(), ByVal al As ArrayList)
i = 1000000000
d = 999999999D
s = "sssssssssssss"
For j As Integer = 0 To a.Length - 1
a(j) += 1
Next
al.Add("add")
End Sub

End Class

得到以下结果:
=====================================
i = 1
d = 1
s = s
a[0] = 1
a[1] = 2
a[2] = 3
al[0] = 1
al[1] = 2
=====================================
=====================================
i = 1
d = 1
s = s
a[0] = 2
a[1] = 3
a[2] = 4
al[0] = 2
al[1] = 3
al[2] = 4
=====================================

这里,被改变的只是两个数组.原因是:它们是引用型的,也就是说,在过程或函数的声明中,若使用Byref来传递参数,此时,属于按址引用,但VB.NET的按址引用是两次复制的结果,包括装箱操作(这一点不用怀疑,确实如此,Byref要慢),若使用Byval则分两种情况:
1、声明为“基本类型”,其中包括特别实现的String类型,如:Byval i as integer,此时,函数中的改变将不被返回。即传统的按值引用。
2、声明为引用类型,如上面的a,al,它们都将被装箱——采取按址方式,如Byval a as integer(),此时,函数中的改变将被返回。原因是在函数声明中,没有实例只有指针,如上面的[Set]函数的Byval a as integer()实际上这里的的a是引用,而不是实例。

16,554

社区成员

发帖
与我相关
我的任务
社区描述
VB技术相关讨论,主要为经典vb,即VB6.0
社区管理员
  • VB.NET
  • 水哥阿乐
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧