Step 1 of 5 · Reading · ~4 min
Learn
Subs, Functions, Arrays
Arrays
By the end of this lesson you can keep many values under one name, size an array from the input, walk it with a loop, swap two elements, and put one loop inside another.
A row of numbered boxes
An array is a row of variables of one type, reached by number. Those numbers are called indexes.
DIM temps(6) AS INTEGER ' 7 elements: temps(0) ... temps(6)
DIM names(1 TO 3) AS STRING ' 3 elements: names(1) ... names(3)
temps(0) = 18
temps(1) = 21
names(1) = "Mon"
BASIC declares the highest index, not the count. DIM temps(6) gives indexes 0 to 6, which is seven elements. Write 1 TO 3 when you want a different lowest index. This is the first habit to unlearn coming from C. New elements start at 0 (or empty text). You can also give starting values: DIM days(0 TO 2) AS INTEGER = {31, 28, 31}.
Bounds
LBOUND(temps) ' 0, the lowest valid index
UBOUND(temps) ' 6, the highest valid index
UBOUND(temps) - LBOUND(temps) + 1 ' 7, the number of elements
UBOUND is an index, not a length. LEN(temps) is no help either: it reports the size in bytes of one element. By default FreeBASIC does not check indexes at run time. Writing temps(7) raises no error; it silently reads or overwrites memory that belongs to something else, and the symptom shows up later, somewhere unrelated.
Sizing at run time
The size is often only known once the program has read the input. Declare the array with empty parentheses and give it its size later with REDIM:
DIM readings() AS INTEGER
REDIM readings(count - 1) ' count elements: 0 to count - 1
Because the number in the parentheses is the last index, a count of count needs count - 1. Resizing again with plain REDIM throws the contents away; REDIM PRESERVE readings(newLast) keeps them.
Walking an array
DIM warm AS INTEGER = 0
DIM i AS INTEGER
FOR i = 0 TO UBOUND(temps)
IF temps(i) > 20 THEN warm = warm + 1
NEXT i
To compare an element with its neighbour, start one step in so that i - 1 is still inside the array:
FOR i = 1 TO UBOUND(temps)
IF temps(i) > temps(i - 1) THEN rises = rises + 1
NEXT i
Looking at the next neighbour, temps(i + 1), means the loop must stop one early, at UBOUND(temps) - 1.
Swapping two elements
To exchange two values you need a third place to hold one of them:
tmp = temps(0)
temps(0) = temps(6)
temps(6) = tmp
Without tmp, temps(0) = temps(6) destroys the old temps(0) before it has been saved, and afterwards both elements hold the same value. FreeBASIC also has a statement that does the same job, SWAP temps(0), temps(6).
A loop inside a loop
The inner loop starts again from its first value on every pass of the outer loop, and its bounds may depend on the outer variable:
DIM r AS INTEGER, c AS INTEGER
FOR r = 1 TO 3
FOR c = 1 TO r
PRINT "*";
NEXT c
PRINT
NEXT r
*
**
***
The trailing ; keeps each * on the same line, and the bare PRINT ends the line. A two-dimensional array takes two indexes: DIM grid(2, 3) AS INTEGER has 3 rows and 4 columns, and grid(1, 2) is row 1, column 2.
Common mistakes
- Reading or writing one past the end. With indexes
0ton - 1, the elementnums(n)does not exist, and no error tells you. Any statement that looks atnums(j + 1)needsjto stop before the last index. - Overwriting a value without saving it first, so one value appears twice and another vanishes.
- Doing one pass over the array when the job needs several. A single sweep that only compares neighbours does not finish the work.
- Declaring
REDIM nums(n)fornvalues. That isn + 1elements, and a loop up toUBOUNDthen handles one extra zero.
Your exercise
Read N integers into the array and print them smallest first, one per line. FreeBASIC ships no sort, so you write it, using the tools above: indexes, a swap and loops inside loops. The starter reads the numbers and prints the array; your code goes between the two.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…