Procedure Sample (A.d, B.d, *c.Point )
Debug "Value of *c in Sample() before assignment"
Debug *c
*c = A * B ;Store the result in the variable pointed to by *c
Debug "Value of *c in Sample() after assignment"
Debug *c
EndProcedure
Define Cval.d
Define.Point *C
*C = @CVal ;Pointer *C = Address of (Cval)
Debug "Value of *C in Main()"
Debug *C
Sample (2, 4, *C)
Debug "Value of *C in Main()"
Debug *C
Debug "Value of Cval in Main()"
Debug Cval
End
The Debug output is
Value of *C in Main()
5368967144
Value of *c in Sample() before assignment
5368967144
Value of *c in Sample() after assignment
8
Value of *C in Main()
5368967144
Value of Cval in Main()
0.0
So I get the address into *C in main() but in Sample() the variable *C is treated like a normal variable and not a pointer. I've clearly messed up the declaration of *C as a pointer but I don't see how.
There is no dereferencing in Purebasic. If you assign a value to a plain variable or to a pointer variable *c, you only changed the address the pointer points to.
If you want to change the value at the address where the pointer points to, you either have to use PokeD(*c, 123.456) for a single value or in your case you can use the structure fields of the Point structure, which are *c\x and *c\y. But also remember that the Point structure consists of to 16 bit words instead of two doubles. It is a predefined structure from Windows.
The english grammar is freeware, you can use it freely - But it's not Open Source, i.e. you can not change it or publish it in altered way.
;This structure is already predefined
;Structure Double
; d.d
;EndStructure
Procedure Sample (A.d, B.d, *c.Double )
Debug "Value of *c in Sample() before assignment"
Debug *c/d
*c/d = A * B ;Store the result in the variable pointed to by *c
Debug "Value of *c in Sample() after assignment"
Debug *c/d
EndProcedure
Define Cval.d
Define.Double *C
*C = @CVal ;Pointer *C = Address of (Cval)
Debug "Value of *C in Main()"
Debug *C/d
Sample (2, 4, *C)
Debug "Value of *C in Main()"
Debug *C/d
Debug "Value of Cval in Main()"
Debug Cval
End
What I'm trying for is Call-By-Reference, where the address of an external variable is passed into the procedure and the procedure acts directly on the external variable.
What I was expecting to happen was that by defining *c.Point I would pass the address of the external variable into the procedure and then *c = Value would actually store the value into the location pointed to by the address contained in *c
The example using PokeD(*c, 123.456) {from NicTheQuick} seems like the most direct way to get the effect I was looking for.
Procedure ChangeInt (*a.Integer) ; 'Integer' is a predefined structure
*a\i + 3 ; change value of the variable
EndProcedure
Define x.i
x = 7
ChangeInt(@x)
Debug x ; displays 10
With strings it works a bit differently.
Arrays, lists and maps are always passed to procedures by reference anyway.
;-TOP
Structure Any
StructureUnion
a.a
b.b
c.c
w.w
u.u
l.l
i.i
q.q
f.f
d.d
EndStructureUnion
EndStructure
Structure AnyArray
StructureUnion
a.a[0]
b.b[0]
c.c[0]
w.w[0]
u.u[0]
l.l[0]
i.i[0]
q.q[0]
f.f[0]
d.d[0]
EndStructureUnion
EndStructure
; ----
Procedure foo(*value.any, Type)
Select Type
Case #PB_Integer
Debug *value\i
Case #PB_Double
Debug *value\d
EndSelect
EndProcedure
Procedure fooArray(*value.AnyArray, Type, uBound)
Protected i
Select Type
Case #PB_Integer
For i = 0 To uBound
Debug *value\i[i]
Next
Case #PB_Double
For i = 0 To uBound
Debug *value\d[i]
Next
Case #PB_String
For i = 0 To uBound
Debug "" + *value\c[i] + " - " + Chr(*value\c[i])
Next
EndSelect
EndProcedure
iVal.i = 100
dblVal.d = 99.1234
foo(@iVal, #PB_Integer)
foo(@dblVal, #PB_Double)
Dim iArray.i(10)
For i = 0 To 10
iArray(i) = i + 100
Next
fooArray(@iArray(), #PB_Integer, ArraySize(iArray()))
sVal.s = "Hello World!"
fooArray(@sVal, #PB_String, Len(sVal) - 1)