【发布时间】:2019-01-12 17:27:29
【问题描述】:
我正在转录代码,它操作复数数组,从 VB 6 到 VB.Net 形式。语言语法变得更加严格,我已经非常仔细地研究了 ByVal 和 ByRef 关键字的使用,这样我就不能根据需要更改或更改通过方法子例程传递的变量。然而,似乎 VB 6 曾经允许我将空变量传递到子例程中,并在调用行中接收更改的(内部计算的)变量。 VB.Net 似乎不允许将空变量作为规则传递给方法子例程?在下面分享的代码 sn-p 中,我只能通过将初始值任意设置为实际在方法子例程中实际定义的参数来避免调用空异常。有没有办法避免这种不雅的开销?
Module Module1
Sub Main()
Dim Sx As Double() = {-0.0053, 0.8882, 0.8882, -0.0053}
Dim Sy As Double() = {-0.0102, -0.4594, -0.4594, -0.0102}
Dim Tx As Double() = {1.0, 1.0, 1.0, 1.0} 'To be calculated by method Stot and passed back to Main!
Dim Ty As Double() = {1.0, 1.0, 1.0, 1.0} 'To be calculated by method Stot and passed back to Main!
Stot(Sx, Sy, Tx, Ty) '[STh]--->[TTh]
Console.WriteLine(Tx(0))
Console.WriteLine(Ty(0))
Console.WriteLine(Tx(1))
Console.WriteLine(Ty(1))
Console.WriteLine(Tx(2))
Console.WriteLine(Ty(2))
Console.WriteLine(Tx(3))
Console.WriteLine(Ty(3))
Stop
End Sub
Public Sub Stot(ByVal Sx As Double(), ByVal Sy As Double(), ByRef Tx As Double(), ByRef Ty As Double())
Dim AA As Double
Dim BB As Double
Dim C As Double
Dim D As Double
Call Cmult(Sx(0), Sy(0), Sx(3), Sy(3), AA, BB)
Call Cdiv(AA, BB, Sx(1), Sy(1), C, D) '(S11*S22)/S21
Tx(0) = Sx(2) - C 'S12-((S11*S22)/S21)
Ty(0) = Sy(2) - D
Call Cdiv(Sx(0), Sy(0), Sx(1), Sy(1), Tx(2), Ty(2)) 'T12=S11/S21
Call Cdiv(Sx(3), Sy(3), Sx(1), Sy(1), Tx(1), Ty(1)) 'T21=S22/S21
Tx(1) = -1 * Tx(1) 'T21=-1*(S22/S21)
Ty(1) = -1 * Ty(1)
Call Cdiv(1, 0, Sx(1), Sy(1), Tx(3), Ty(3)) 'T22=1/S21
End Sub
Public Sub Cdiv(ByVal X1 As Double, ByVal Y1 As Double, ByVal X2 As Double, ByVal Y2 As Double, ByRef X3 As Double, ByRef Y3 As Double)
Dim Denom As Double
Denom = X2 * X2 + Y2 * Y2 'Multiplication by conjugate (X2+iY2)(X2-iY2)
X3 = (X1 * X2 + Y1 * Y2) / Denom
Y3 = (Y1 * X2 - X1 * Y2) / Denom
End Sub
Public Sub Cmult(ByVal X1 As Double, ByVal Y1 As Double, ByVal X2 As Double, ByVal Y2 As Double, ByRef X3 As Double, ByRef Y3 As Double)
X3 = X1 * X2 - Y1 * Y2
Y3 = X1 * Y2 + Y1 * X2
End Sub
End Module
子程序 StoT 正在将 S 参数矩阵转换为 T 参数矩阵:一个常见的微波工程任务。它在做什么并不重要,它只是作为一个例子:如何在 VB.Net 中编写这种形式的数据共享是重点。此控制台应用程序将数组参数定义为 Double():双精度数数组 - 复数 X 和 Y 分量的单独数组(在 Main 方法中)。我知道数组在 VB.Net 中自动获得引用类型,因此无需在调用的子例程中将传递的参数定义为 ByVal 或 ByRef:StoT。我再重复一遍:我只能通过在主定义中为输出参数 Tx() 和 Ty() 预定义任意值来使这个调用工作而不在 StoT 中调用空异常。 为了完成所需的算术任务,方法 StoT 需要执行复杂的除法和复杂的乘法任务,这些任务在方法子例程中编码:CDiv() 和 CMult()。同样,这些接受并提供输出双精度数字,遵循数字只能使用 ByRef 关键字作为输出数字提供的规则。然而,这些调用不会调用空异常,即使它们生成了一个不预先存在的答案复数。所以我的问题是为什么会这样。好像有不一致的地方......
【问题讨论】:
-
对不起,我不明白。如果此代码有效,您将进行哪些更改以使其引发空引用异常?
标签: arrays vb.net methods parameter-passing subroutine