Primitive Data Types
Blitz Basic / AmiBlitz supports seven standard data types that can be stored in variables by your program. Six of these are used to store numbers in various formats, and a string data type is used to store strings of characters (text). The various properties and limitations of each type are listed below:
|Byte||.b||1 byte (8 bits)||-128||+127||Integer values only|
|Word||.w||2 bytes (16 bits)||-32768||+32767||Integer values only|
|Long / Long Word||.l||4 bytes (32 bits)||-231||+231||Integer values only|
|Quick||.q||4 bytes (32 bits)||-32768||+32767||Quick-float with fixed decimal point, +/-15 bit.16 bit format (1 in 65536 precision after decimal point). Quicker than emulating the float types in software but slower than integers and slower than float types using a hardware FPU.|
|Float||.f||4 bytes (32 bits)||-9*1018||+9*1018-1||Single-precision floating point number as supported by the Amiga's standard floating point libraries, +/-23bits+/-7 bits format. Slow to emulate in software but very fast if hardware FPU is used. Slower than integers.|
|Double Float||.d||8 bytes (64 bits)||-Huge||+Huge||Double-precision floating point number, +/-52bits+/-10 bits format. No software emulation so requires a hardware FPU to be used. Not supported in Blitz Basic 2.1 and earlier. Slower than single-precision float types.|
|String||.s or $||Variable, dynamically increased as required||Null (\0)||String buffer size||String of 8-bit characters in memory terminated automatically by a null character (\0). Size does not normally need to be declared. $ extension is included as in other BASIC dialects, and if used, must be included every time the variable is referenced.|
Note: All numerical types are signed.
Declaring Data Types
By default, any variables used in Blitz that are not explicitly declared as a particular type are created as quick types. The default type for variables not explicitly defined can be set using the DEFTYPE statement:
In this example, all further variables created without a declared type will be of the byte type.
To declare specific variables as an explicit type, the DEFTYPE statement can be used by supplying the names of one or more variables in addition to the type required. For example:
DEFTYPE .b status
DEFTYPE .l result, attribute
In this example, the variable status is a byte type, and the variables result and attribute are long types. The default type for unspecified variables is still quick.
Blitz allows you to also declare the type of variable the first time it is used, for example:
result.w = 25000
After this line, result is defined as a word type and the .w extension is no longer required.
If any variable overflows beyond its specified range, an error is not normally generated. Instead, the value wraps around to the opposite end of the scale. This can lead to some very difficult to find bugs being introduced into your code! For example:
MyNum.b = 120
MyNum = MyNum + 10
This code might be expected to print out the number 130, but instead it will print the number -126, since once it goes above +127 it wraps around, and the remaining 3 are counted starting at -128. The runtime debugger can be set to give an error for these situations during debugging which can help to spot these problems during development, but bear in mind that it can also cause false alarms in certain cases where unsigned values are used by OS calls for example. Overflows when your executable is running without the debugger won't cause a crash by themselves, but the resulting incorrect value could cause unexpected behaviour or even crashes if an incorrect memory address is calculated for example. So it's important to always use an appropriate type for the information required to be contained in a variable!
NewTypes are complex data types custom-defined by your code. They contain one or more variables of any type grouped together. They are the equivalent of a Struct or Structure in C. The NEWTYPE statement is used to define a NewType structure, which can then be used similarly to the built-in primitive types. For example:
DEFTYPE .coord MyLocation
This example defines a new type called .coord, which contains an x and a y value both of the word type, and then declared the new variable MyLocation as type .coord. The elements contained in a NewType can be accessed using the backslash character after the variable name. For example:
MyLocation\x = 55
MyLocation\y = 72
NPrint "Co-ordinates: ", MyLocation\x, " by ", MyLocation\y
This example will print:
Co-ordinates: 55 by 72
NewTypes can contain any number of elements, and elements can be of any type, including other NewTypes previously declared. For example:
DEFTYPE .ship enemy, player
This example defines a new .ship type containing a string, a long word and a .coord type which we previously declared to contain two word types. Accessing these sub elements uses an additional backslash character:
enemy\name = "The Enemy"
enemy\location\x = 25
enemy\location\y = 3
Note: Strings within NewTypes must use the .s extension; the $ extension is not allowed here.
Arrays Within NewTypes
It is also possible for NewTypes to include arrays in their structure, however some limitations apply:
- They must be a single dimension
- Their size must be declared by a constant
- Indices are referenced using square brackets instead of the usual curved brackets
- Their size is the total number of elements, not the index of the last element as in normal arrays, so an array declared inside a NewType with a size of 4 contains elements with indexes from 0 to 3 only
An example of an array within a NewType is shown below:
DEFTYPE .contact MyContact
MyContact\email = "email@example.com"
MyContact\email = "firstname.lastname@example.org"
This example shows a .contact NewType which contains an array of strings for holding up to 5 email addresses. These are indexed 0 to 4. Trying to access MyContact\email will result in an error!