2017-05-20 57 views
0

所以我有一個「主」功能(SolveSixODES),它調用一個輔助功能(AllODEs)。當它這樣做時,主函數中的x值會被修改。我不明白這是怎麼可能的,因爲它不是一個全球變量。另一個函數中的局部變量如何影響主函數中的變量?

下面是代碼,是我的輸入I使用如下:

x = 0時,XMAX = 3,Y = 0-6,H = 0.1,誤差= 0.1

Public Function SolveSixODE(x As Double, xmax As Double, Y As Range, h As Double, error As Double) 'Weird bug: You must leave the first y4 value blank 

Dim i As Integer, k(7, 7) As Double, j As Integer, m As Integer            'k(Order #, equation #) 
Dim Y5(7) As Double, Y4(7) As Double, Y4Old(7) As Double 
Dim delta0(7) As Double, delta1(7) As Double, delRatio(7) As Double, Rmin As Double 

For i = 1 To 6     'Moving the input data so it can acutally be used 
    Y4(i) = Y(i) 
Next i 

While x < xmax 

    If x + h < xmax Then 
     x = x + h 
    Else 
     h = xmax - x 
     x = xmax 
    End If 

    For j = 1 To 6               'j is the order i is equation number 
     For i = 1 To 6              'Calculating all of the k(1) values for eq 1 to 6 
      k(j, i) = AllODES(x, Y4, i, j, k, h) '!!!!!SOME HOW THIS LOOP MAKES X negative...!!!!!!! 
     Next i 
    Next j 

    For i = 1 To 6 
     Y4Old(i) = Y4(i)             'Saving old y4 value to calc delta0 
     Y4(i) = Y4(i) + h * (k(1, i) * (37/378) + k(3, i) * (250/621) + k(4, i) * (125/594) + k(6, i) * (512/1771)) 
     Y5(i) = Y4(i) + h * (k(1, i) * (2825/27648) + k(3, i) * (18575/48384) + k(4, i) * (13525/55296) + k(5, i) * (277/14336) + k(6, i) * (0.25)) 

     delta0(i) = error * (Abs(Y4Old(i)) + Abs(h * AllODES(x, Y4Old, i, 1, k, h))) 'First order because we don't want to use the k vals 
     delta1(i) = Abs(Y5(i) - Y4(i)) 
     delRatio(i) = Abs(delta0(i)/delta1(i))        'Ratio of errors 
    Next i 

    Rmin = delRatio(1) 

    For i = 2 To 6 
     If delRatio(i) < Rmin Then 
      Rmin = delRatio(i)            'Determine the smallest error ratio 
     End If 
    Next i 

    If Rmin < 1 Then              'If this is true then the step size was too big must repeat step 
     x = x - h               'Set x and y's back to previous values 
     For i = 1 To 6 
      Y4(i) = Y4Old(i) 
     Next i 
     h = 0.9 * h * Rmin^0.25           'adjust h value; 0.9 is a safety factor 
    Else 
     h = 0.9 * h * Rmin^0.2           'Otherwise, we march on 
    End If 
    m = m + 1 
Wend 

SolveSixODE = Y4 

End Function 

Public Function AllODES(x As Double, Y() As Double, EqNumber As Integer, order As Integer, k() As Double, h As Double) As Double 

Dim conc(7) As Double, i As Integer, j As Integer 

If order = 1 Then 
    x = x - h 
    For i = 1 To 6            'Movin the data so I can use it 
     conc(i) = Y(i)           'also adjusting the x and y values for RK4 (Cash Karp values) 
    Next i 

ElseIf order = 2 Then 
    x = x - h + h * 0.2 
    For i = 1 To 6 
     conc(i) = Y(i) + h * k(1, i) * 0.2 
    Next i 

ElseIf order = 3 Then 
    x = x - h + 0.3 * h 
    For i = 1 To 6 
     conc(i) = Y(i) + h * (0.075 * k(1, i) + 0.225 * k(2, i)) 
    Next i 

ElseIf order = 4 Then 
    x = x - h + 0.6 * h 
    For i = 1 To 6 
     conc(i) = Y(i) + h * (0.3 * k(1, i) - 0.9 * k(2, i) + 1.2 * k(3, i)) 
    Next i 

ElseIf order = 5 Then 
    x = x - h + h 
    For i = 1 To 6 
     conc(i) = Y(i) + h * ((-11/54) * k(1, i) + 2.5 * k(2, i) - (70/27) * k(3, i) + (35/27) * k(4, i)) 
    Next i 

ElseIf order = 6 Then 
    x = x - h + 0.875 * h 
    For i = 1 To 6 
     conc(i) = Y(i) + h * ((1631/55296) * k(1, i) + (175/512) * k(2, i) + (575/13824) * k(3, i) + (44275/(110592) * k(4, i) + (253/4096) * k(5, i))) 
    Next i 
Else 
    MsgBox ("error") 
End If 


If EqNumber = 1 Then           'These are the actual equations 
    AllODES = x + Y(1) 

ElseIf EqNumber = 2 Then 
    AllODES = x 

ElseIf EqNumber = 3 Then 
    AllODES = Y(3) 

ElseIf EqNumber = 4 Then 
    AllODES = 2 * x 

ElseIf EqNumber = 5 Then 
    AllODES = 2 * Y(2) 

ElseIf EqNumber = 6 Then 
    AllODES = 3 * x 

Else 
    MsgBox ("You entered an Eq Number that was dumb") 
End If 

End Function 

這是可能是因爲我錯過了一些非常微不足道的東西,但這似乎與我對變量如何工作的認識相矛盾。所以如果你理解函數在這種情況下如何處理來自另一個函數的變量,我將不勝感激任何建議和/或解釋!

提前致謝!

回答

3

主函數中的x值被修改。我不明白,這可怎麼是可能的,看到它是不是一個全局變量

這是正常的,因爲你逝去的x參照的功能AllODES和你改變它。當在功能/子原型中沒有明確指定關鍵字ByVal時,默認傳遞機制是ByRef,即,通過引用

Public Function AllODES(x As Double, ... 

意味着

Public Function AllODES(ByRef x As Double, .... 

我們觀察到X 在此功能操作,所以變化將出現在來電者

Public Function AllODES(ByVal x As Double, .... 
'      ^^^^^ 

只有在這種情況下,主叫方的x和被叫的x將是兩個不同的:如果你想要的是x的變化不會在調用者的範圍報到,由值傳遞X 變量。

相關問題