Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Variable as a reference or value to a function
#11
From: Microsoft QuickBasic 4 - Programmieren in Basic - Ausgewählte Themen

[Image: QBasic-Referenz-Kl.jpg]
Reply
#12
@KernelPanic,
Something is lost in translation. It would help to show code and not screen shots. Also it would help if you quit assuming we can read German.

Also while QB64 tries to be as compatible as possible to old QB's there are places where it is not. And default pass by reference is one of those areas, so don't quote old QB reference (which did pass by value as default), which is out-of-date.

Quote from current QB64 Wiki where you are finding discrepancy.
b = b + ...
Reply
#13
I will try again:
Code: (Select All)
Dim ALong As Long
Dim BInteger As Integer

BInteger = 1
Print "Binteger is"; BInteger
temp& = passMeALongTypeAndIWillChangeIt&(BInteger)
Print "Binteger after call to Function is"; BInteger; " NOT changed! so effectively passed BInteger by Value"
Print: Print
ALong = 1
Print "Along is"; ALong
temp& = passMeALongTypeAndIWillChangeIt&(ALong)
Print "ALong after call to Function is"; ALong; " changed because ALong is same Type as defined in Function so effectively passed by Reference."

Function passMeALongTypeAndIWillChangeIt& (i As Long)
    i = i * 10
    Print "Inside passMeALongTypeAndIWillChangeIt& i ="; i
    passMeALongTypeAndIWillChangeIt& = whoCares
End Function
b = b + ...
Reply
#14
Functions will pass by reference in the exact same manner as subs.  The main rule of thumb is that variable types *must* match to pass.

Examples:
Code: (Select All)
DIM x AS INTEGER
x = 0
PRINT Foo(x)
PRINT Foo(x)
PRINT Foo(x)

FUNCTION Foo (X AS INTEGER)
  X = X + 1
  Foo = 2 * X
END FUNCTION

Now, the above will print 2, 4, 6 onto the screen, as the value of X changes and is passed back to the main routine with each run of the function.


Code: (Select All)
DIM x AS _FLOAT
x = 0
PRINT Foo(x)
PRINT Foo(x)
PRINT Foo(x)

FUNCTION Foo (X AS INTEGER)
  X = X + 1
  Foo = 2 * X
END FUNCTION

And the above will print 2, 2, 2 on the screen, as the function Foo uses an Integer, and the main module is passing a _FLOAT.  The two variable types aren't the same, so the value won't pass by reference.

For SUBs and for FUNCTIONs, variables pass by reference as long as the types match.
Reply
#15
The reason your initial code passes by value to the sub is the use of double brackets
Call MySub(a) ' passes reference to a
Call MySub((a)) ' evaluates (a) to tempvalue and passes reference to tempvalue

(Same is true for Functions btw)

btw i prefer to write (and read):
MySub a 'byref
MySub (a) 'byval
45y and 2M lines of MBASIC>BASICA>QBASIC>QBX>QB64 experience
Reply
#16
Ok, I think I have understood it now. This tip from Steve was crucial (Thanks!):
For SUBs and for FUNCTIONs, variables pass by reference as long as the types match.

The variable must be explicitly changed in the function.
AsValue = input * 3 -- this doesn't work. This doesn't work even if the variable types match.

Same goes for C. I've been trying to change the value at the address of the variable for over two hours. Now it worked. 


Code: (Select All)
'Uebergabe von Variablen an Funktionen als Referenz oder Wert.
'Variablen an Funktionen werden auf genau die gleiche Weise wie
'an Subs als Referenz'uebergeben. Dabei lautet die wichtigste
'Faustregel: Die Variablentypen muessen uebereinstimmen,
'um als Referenz zu gelten.
'
'Bei SUBs und bei FUNCTIONs werden Variablen als Referenz uebergeben,
'solange die Eingabewertpen uebereinstimmen, sonst werden sie
'nur als Wert uebergeben.
'Steve McNeill - 18. Juli 2022

Option _Explicit

Dim eingaberef As Integer
Dim eingabewert As _Float

Input "Eingabe: ", eingaberef

Print AlsReferenz(eingaberef)
Print AlsReferenz(eingaberef)
Print AlsReferenz(eingaberef)

'Der urspruengliche Wert der Variablen wurde veraendert
'Zugriff auf die Adresse
Print Using "Eingabe ist jetzt: ###"; eingaberef

Print
Input "Eingabe als Wert: ", eingabewert
Print AlsWert(eingabewert)
Print AlsWert(eingabewert)
Print AlsWert(eingabewert)

'Die Eingabetypen stimmen nicht ueberein: Float an Integer
'Es wird mit einer Kopie der Variablen gearbeitet
'daher keine Aenderung der urspruenglichen Variablen
Print Using "Eingabe ist nicht veraendert: ###"; eingabewert

End 'Hauptprogramm

Function AlsReferenz (eingaberef As Integer)

  'Nur so wird die Variable veraendert
  eingaberef = eingaberef * 3
  AlsReferenz = eingaberef 'Das bringt nichts: (eingaberef + 3)
End Function

Function AlsWert (eingabewert As Integer)
  eingabewert = eingabewert + 1
  AlsWert = 2 * eingabewert
End Function
Reply
#17
Hi friends
about this thumb up rule showed at #13 by Steve
We must admit that it is ok but just different from QBasic.
In Qbasic , for using FUNCTION and SUB, it needs DECLAREtion of prototype of SUB or FUNCTION at the beginning of the code file.
So if you use a different type of data in passing parameter you got an Error for Data Mysmatch on running the code.
See next time
Good Coding
Reply
#18
(07-18-2022, 03:38 PM)mdijkens Wrote: The reason your initial code passes by value to the sub is the use of double brackets
Call MySub(a) ' passes reference to a
Call MySub((a)) ' evaluates (a) to tempvalue and passes reference to tempvalue

(Same is true for Functions btw)

btw i prefer to write (and read):
MySub a 'byref
MySub (a) 'byval
I don't think that enclosing the argument in parenthesis forces the argument to be treated as by value, at least not in the code I am trying to debug
honestly, why in the world doesn't QB64 have byval and byref for arguments to sub's and functions?
in another thread I posted a portion of Treebeards string math routines, the basic 4 functions seem to work but the Sqr function and the trig functions don't work, tried it in VB.net and at first I was getting no result until I changed the parameters that I could guess were meant to be modified to byref, then all the functions worked including the Sqr, logs and trigs
Reply
#19
(08-08-2022, 02:14 PM)Jack Wrote:
(07-18-2022, 03:38 PM)mdijkens Wrote: The reason your initial code passes by value to the sub is the use of double brackets
Call MySub(a) ' passes reference to a
Call MySub((a)) ' evaluates (a) to tempvalue and passes reference to tempvalue

(Same is true for Functions btw)
I don't think that enclosing the argument in parenthesis forces the argument to be treated as by value, 

Try it. It is really true!


Code: (Select All)
x = 3
subproc x
Print "passed byref:"; x ' prints 4

x = 3
subproc (x)
Print "passed byval:"; x ' prints 3

x = 3
Call subproc(x)
Print "passed byref:"; x ' prints 4

x = 3
Call subproc((x))
Print "passed byval:"; x ' prints 3

End

Sub subproc (a)
  a = a + 1
End Sub
45y and 2M lines of MBASIC>BASICA>QBASIC>QBX>QB64 experience
Reply
#20
Does not work for strings


Code: (Select All)
x$ = "3"
subproc x$
Print "passed byref:"; x$ ' prints 4

x$ = "3"
subproc (x$)
Print "passed byval:"; x$ ' prints 3

x$ = "3"
Call subproc(x$)
Print "passed byref:"; x$ ' prints 4

x$ = "3"
Call subproc((x$))
Print "passed byval:"; x$ ' prints 3

End

Sub subproc (a$)
    a$ = _Trim$(Str$(Val(a$) + 1))
End Sub
b = b + ...
Reply




Users browsing this thread: 10 Guest(s)