PDA

View Full Version : [QOD] Guess the output (Union)



ErosOlmi
08-02-2013, 18:55
Giving the following UNION and relative variable ...



Union MyUnion
b(12) As Byte
st As String * 12
End Union

Dim MyU As MyUnion


Giving one of the following two methods to fill the union array b ...



'---Method 1 to fill UDT array
With MyU
.b( 1) = 116
.b( 2) = 104
.b( 3) = 105
.b( 4) = 110
.b( 5) = 66
.b( 6) = 97
.b( 7) = 115
.b( 8) = 105
.b( 9) = 99
.b(10) = 32
.b(11) = 33
End With

'---Method 2 to fill UDT array
With MyU
.b( 1) = 116, 104, 105, 110, 66, 97, 115, 105, 99, 32, 33
End With


What will be the output of:

MsgBox 0, MyU.st

Petr Schreiber
08-02-2013, 22:18
Hehe,

since PB/DOS I have the ASCII table in my head, so I am quite sure the result will be "thinBASIC !" :)

UNIONs are cool feature when porting from other languages, but in practice I use more the DIM .. AT syntax to achieve same result in most projects.

I think in this special case it is enough to have the array dimensioned to 11 elements and the string to 11 characters.

Why?

Because STRING * n is not null terminated, which is the difference compared to ASCIIZ * n.

So the code could be in theory this (added one method for array fill):


Union MyUnion
b(11) As Byte
st As String * 11
End Union

Dim MyU As MyUnion

'---Method 1 to fill UDT array
With MyU
.b( 1) = 116
.b( 2) = 104
.b( 3) = 105
.b( 4) = 110
.b( 5) = 66
.b( 6) = 97
.b( 7) = 115
.b( 8) = 105
.b( 9) = 99
.b(10) = 32
.b(11) = 33
End With

'---Method 2 to fill UDT array
With MyU
.b( 1) = 116, 104, 105, 110, 66, 97, 115, 105, 99, 32, 33
End With

'---Method 3 to fill UDT array
MyU.b( 1) = 116, 104, 105, 110, 66, 97, 115, 105, 99, 32, 33

MsgBox 0, MyU.st



Petr

ReneMiner
09-02-2013, 00:23
I always wanted to know what that "Union" does.

Now I think I've learned from this thread that st and b of myU refer to the same adress in memory and both display the same values stored as different types. Just for interest: I could replace some "cast"-Methods (cstr, cbyte etc.) by using a Union, for example I could use


Union someUnion
l as long
b(4) as Byte
End Union

dim myU as someUnion
myU.l = 123456


' now the b()-bytes show the value 123456 split up to &H00, &H01, &HE2 and &H40 ? Cool.

ErosOlmi
09-02-2013, 10:08
@Petr: right you are.
ASCIIZ * n needs 12 bytes (due to NULL at the end) while for STRING * n 11 bytes are enough.


@ReneMiner

... st and b of myU refer to the same address in memory and both display the same values stored as different types.
Exactly: every element into an UNION shares the same memory area with all the other elements.
The total memory area occupied by an UNION is the size of the longest element present into the UNION.

Here a little more interesting UNION example


Uses "console"


'---3 different structures each of which representing a thing: dog, orange, coin
Type Dog
lBreed As Long
lAge As Byte
sName As String * 16
End Type

Type Orange
lSize As Byte
End Type

Type Coin
lCountry As Long
End Type


'---Put all the things together into an union so they all share the same memory area
Union ThingProperties
tDog As Dog
tOrange As Orange
tCoin As Coin
End Union


'---Now creates a general purpose thing able to represent all the possible things
Type Thing
lThingType As Long
uThingProp As ThingProperties
End Type


'---Possible things type
%ORANGE = 1
%COIN = 2
%DOG = 3


'---Allocate few things
Dim tThing(3) As Thing
Dim lCurrentThing As Long


'---Fill things with a thing type and thing data
tThing(1).lThingType = %ORANGE
tThing(1).uThingProp.tOrange.lSize = 25


tThing(2).lThingType = %COIN
tThing(2).uThingProp.tCoin.lCountry = 1234


tThing(3).lThingType = %DOG
tThing(3).uThingProp.tDog.sName = "FUFFY"

'---Show something a bout the things
For lCurrentThing = 1 To UBound(tThing)
Print "Thing is ... "
Select Case tThing(lCurrentThing).lThingType
Case %ORANGE
PrintL "an Orange of size" , tThing(lCurrentThing).uThingProp.tOrange.lSize
Case %COIN
PrintL "a Coin by country" , tThing(lCurrentThing).uThingProp.tCoin.lCountry
Case %DOG
PrintL "a Dog whose name is" , tThing(lCurrentThing).uThingProp.tDog.sName
End Select
Next


WaitKey