Previous | Contents | Index |
Terminal-format files let you perform simple I/O to disk files. The records in a terminal-format file must be accessed sequentially. That is, you must access the records in the file one by one, from the first to the last. You can add new records only at the end of the file.
Just as the INPUT, LINPUT, and INPUT LINE statements receive information from a terminal, the INPUT #, LINPUT #, and INPUT LINE # statements receive information from a terminal-format file. And, as the PRINT statement sends information to the terminal, the PRINT # statement sends information to a terminal-format file.
Terminal-format files are useful for creating files to be printed on a line printer, or for supplying a program with moderate amounts of input. However, if you want to use the same file for both input and output, you should not use terminal-format files. Instead, use sequential, relative, or indexed files. For more information, see Chapter 14.
You do not have to use a program to create a terminal-format file. You
can use a text editor to create a file and insert data, then use a
BASIC program to open the file and retrieve the data.
6.3.1 Opening and Closing a Terminal-Format File
You use the OPEN statement to create a file, or to gain access to an existing file. If you do not specify either FOR INPUT or FOR OUTPUT in the OPEN statement, BASIC tries to open an existing file. If the file does not exist, BASIC creates a new one.
The channel specification lets you associate a number with the file for as long as the file is open. All I/O operations to or from the file use this number.
When you are finished accessing a file, you close it with the CLOSE
statement.
6.3.2 Writing Records to a Terminal-Format File
The following example receives information from a terminal, then writes the information to a terminal-format file as a report:
PRINT "This program creates a daily sales report file named SALES.DAT" OPEN "SALES.DAT" FOR OUTPUT AS FILE #4% PRINT #4%, "Salesperson","Sales Area","Items Sold" PRINT #4% INPUT "How many salespersons for today's report"; sales_persons% FOR I% = 1% TO sales_persons% INPUT "Salesperson's name"; s_name$ INPUT "Sales area"; area$ INPUT "Number of items sold"; items_sold% PRINT #4%, s_name$, area$, items_sold% NEXT I% CLOSE #4% END |
This program creates a daily sales report file named SALES.DAT How many salespersons for today's report? 3 Salesperson's name? JONES Sales area? NJ Items sold? 5 Salesperson's name? SMITH Sales area? NH Items sold? 6 Salesperson's name? BAINES Sales area? VT Items sold? 8 |
This program first prints a header explaining its purpose, then opens a terminal-format file on channel 4. After this file is opened, the two PRINT # statements place an explanatory header followed by a blank line into the file.
The program then prompts you for the number of salespersons for which data is to be entered. The FOR...NEXT loop prompts for the name, sales area, and items sold for each salesperson. The FOR...NEXT loop executes only as many times as there are salespersons. See Chapter 10 for more information about FOR...NEXT loops.
After the data has been entered for each salesperson, the program writes this information to the terminal-format file. Because the response to the first question was 3, the FOR...NEXT loop executes three times.
After the last item has been printed to the file, the program closes the file and ends. When you display the file with the DCL command TYPE, you see that the information is printed under the proper headers. You can also print the file on a line printer. The PRINT # statement formats the output in print zones as the PRINT statement does.
$ TYPE SALES.DAT Salesperson Sales Area Items Sold JONES NJ 5 SMITH NH 6 BAINES VT 8 |
An array is a set of data that is ordered in any number of dimensions.
This chapter describes how to create and use BASIC arrays.
7.1 Overview of Arrays
A one-dimensional array is called a list or vector. A two-dimensional array is called a matrix. BASIC arrays can have up to 32 dimensions, and a specific type of BASIC arrays can be redimensioned at run time. In addition, you can specify the data type of the values in an array by using data type keywords or suffixes.
The subscript of an element in an array defines that element's position in the array. When you create an array, you specify:
BASIC arrays are zero-based by default; that is, when calculating the number of elements in a dimension, you count from zero to the number of elements specified. For example, an array with an upper bound of 10 and no specified lower bound has 11 elements: 0 to 10, inclusive. The array My_array(3,3) has 16 elements: 0 to 3 in each dimension, or 42.
BASIC also lets you specify a lower bound for any or all dimensions in an array, unless the array is a virtual array. By specifying lower and upper bounds for arrays, you can make your array subscripts meaningful. For example, the following array contains sales information for the years 1990 to 1999:
DECLARE REAL Sales_data(1990 TO 1999) |
To refer to an element in the array Sales_data, you need only specify the year you are interested in. For example, to print the information for the year 1999, you would type:
PRINT Sales_data(1999) |
You can create arrays either implicitly or explicitly. You implicitly create arrays having any number of dimensions by referencing an element of the array. If you implicitly create an array, BASIC sets the upper bound to 10 and the lower bound to zero. Therefore, any array that you create implicitly contains 11 elements in each dimension.
The following example refers to the array Student_grades. If the array has not been previously declared, BASIC will create a one-dimensional array with that name. The array contains 11 elements.
Student_grades(8) = "B" |
You create arrays explicitly by declaring them in a DIM, DECLARE, COMMON, or MAP statement, or record declaration. Note that if you want to specify lower bounds for your array subscripts, you must declare the array explicitly.
When you declare an array explicitly, the value that you give for the upper bound determines the maximum subscript value in that dimension. If you specify a lower bound, then that is the minimum subscript value in that dimension. If you do not specify a lower bound, BASIC sets the lower bound in that dimension to zero. You can specify bounds as either positive or negative values. However, the lower bound of each dimension must always be less than or equal to the upper bound for that dimension.
You can use MAT statements to create and manipulate arrays; however,
MAT statements are valid only on arrays of one or two dimensions. In
addition, the lower bounds of all dimensions in an array referenced in
a MAT statement must be zero.
7.2 Creating Arrays Explicitly
You can create arrays explicitly with four BASIC statements: DECLARE, DIMENSION, COMMON, and MAP.
In addition, you can declare arrays as components of a record data type. See Chapter 9 for more information about records.
Normally, you use the DECLARE statement to create arrays. However, you might want to create the array with another BASIC statement as follows:
When you create an array, the bounds you specify determine the array's size. The maximum value allowed for a bound can be as large as 2147483467; however, this number is actually limited by the amount of virtual storage available to you. Very large arrays and arrays with many dimensions can cause fatal errors at both compile time and run time.
The following restrictions apply to arrays:
The DECLARE statement creates and names variables and arrays. All elements of arrays created with the DECLARE statement are initialized to zero or the null string. The following statement creates a longword integer array with 11 elements:
DECLARE LONG FIRST_ARRAY(1980 TO 1990) |
Note that the STRING data type with the DECLARE statement causes the
creation of an array of dynamic strings. To create an array of
fixed-length strings, declare the array in a COMMON or MAP statement or
as part of a RECORD structure.
7.2.2 Creating Arrays with the DIM Statement
The DIM statement creates and names one or more arrays. Use the DIM statement to create an array when you want to:
When creating arrays with the DIM statement, you specify the data type of the array elements with a data type keyword, a special suffix on the array name, or both. The array name can be any valid variable name. If you do not supply a data type keyword, the data type is determined by the suffix of the array name:
Even if the DIM statement contains a data type keyword, the array name can still end in the appropriate data type suffix. This makes the data type of the array immediately obvious.
The DIM statement can be either executable or declarative. If the specified bounds are constants, the DIM statement is declarative. This means that the storage is allocated at compile time, and the array cannot appear in any other DIM statement.
However, if any of the specified bounds are variables (simple or subscripted), the DIM statement is executable. This means that the storage for the array is allocated at run time, and the array can be redimensioned with a DIM statement any number of times.
In the DIM statement, bounds can be either constants or variables (simple or subscripted), but not expressions. |
When an array is redimensioned with the executable DIM statement, the array can become larger or smaller than it was. However, redimensioning an array in this way causes it to be reinitialized, and all data in the array is lost.
In contrast, MAT statements let you redimension an array to be the same
size or smaller than it was. However, MAT statements redimension arrays
only when assigning values or performing matrix I/O; therefore, the
fact that MAT statements reinitialize the array does not matter. See
Section 7.6 for more information about MAT statements.
7.2.2.1 Declarative DIM Statements
Declarative DIM statements have integer constants as bounds. The percent sign is optional for bounds; however, BASIC signals the error "Integer constant required" if a constant bound contains a decimal point. The following statement creates a 101-element virtual array containing string data. The elements of this array can each have a maximum length of 256 characters.
DIM #1%, STRING VIRT_ARRAY(100) = 256% |
The following restrictions apply to the use of declarative DIM statements:
Executable DIM statements have at least one variable bound. Bounds can be constants or simple variables, but at least one bound must be a variable. Executable DIM statements let you redimension an array at run time. The bounds of the array can become larger or smaller, but the number of dimensions cannot change. For example, you cannot redimension a four-dimensional array to be five-dimensional.
The executable DIM statement cannot be used on arrays in COMMON, MAP, DECLARE, or declarative DIM statements, nor on virtual arrays or arrays received as formal parameters.
Whenever an executable DIM statement executes, it reinitializes the array. If you change the values of an executable DIM statement, the initial values are reset each time the DIM statement is executed.
In the following example, the second DIM statement reinitializes the array real_array; therefore, real_array(1%) equals zero in the second PRINT statement:
X% = 10% Y% = 20% DIM real_array(X%) real_array(1%) = 100 PRINT real_array(1%) DIM real_array(Y%) PRINT real_array(1%) END |
100 0 |
You cannot reference an array named in an executable DIM statement
until after the DIM statement executes. If you reference an array
element declared in an executable DIM statement whose subscripts are
larger than the bounds specified in the last execution of the DIM
statement, BASIC signals the run-time error "Subscript out of
range" (ERR = 55), provided subscript checking is enabled.
7.2.3 Creating Arrays with the COMMON Statement
Create arrays with the COMMON statement when you need an array of fixed-length strings, or when you want to share an array among program modules. Program modules can share arrays in COMMON statements by defining a common block with the same name.
The COMMON statements in the following programs create a 100-element array of fixed-length strings, each element 10 characters long. Because the main program and subprograms use the same common name, the storage for these arrays is overlaid when the programs are linked; therefore, both programs can read and write data to the array.
!Main Program COMMON (ABC) STRING access_list(1 TO 100) = 10 |
!Subprogram SUB SUB1 COMMON (ABC) STRING new_list(1 TO 100) = 10 |
Create arrays with the MAP statement only when you want the array to be part of a record buffer, or when you want to overlay the storage containing the array. Note that string arrays in maps are always fixed-length.
You associate the array with a record buffer by naming the map in the MAP clause of the OPEN statement.
In the following example, the MAP statement creates two arrays: an 11-element fixed-length string array named team and a 33-element array of WORD integers named bowling_scores. Because the OPEN statement specifies MAP ABC, the storage for these arrays is used as the record buffer for the open file.
MAP (ABC) STRING team(10) = 20, WORD bowling_scores(0 TO 32) OPEN "BOWLING.DAT" AS FILE #1%, SEQUENTIAL VARIABLE, MAP ABC |
Create arrays implicitly as follows:
When you first create an implicit array, the lower bound is zero and the upper bound is 10. An array created by referencing an element can have up to 32 dimensions in BASIC. An array created with a MAT statement can have only one or two dimensions.
The ability to create arrays implicitly exists for compatibility with previous implementations of BASIC. However, it is better programming practice to declare all arrays explicitly before using them. |
If you reference an element of an array that has not been explicitly declared, BASIC creates a new array with the name you specify. Arrays created by reference have default subscripts of (0 TO 10), (0 TO 10, 0 TO 10), (0 TO 10, 0 TO 10, 0 TO 10), and so on, depending on the number of dimensions specified in the array reference. For example, the following program implicitly creates three arrays and assigns a value to one element of each:
LET A(5,5,5) = 3.14159 LET B%(3) = 33 LET C$(2,2) = "Russell Scott" END |
The first LET statement creates an 11-by-11-by-11 array that stores floating-point numbers and assigns the value 3.14159 to element (5,5,5). The second LET statement creates an 11-element list that stores integers and assigns the value 33 to element (3), and the third LET statement creates an 11-by-11 string array and assigns the value "Russell Scott" to element (2,2).
When you create an implicit numeric array by referring to an element, BASIC initializes all elements (except the one assigned a value) to zero. For implicit string arrays, BASIC initializes all elements (except the one assigned a value) to a null string. When you implicitly create an array, you cannot specify a subscript greater than 10. An attempt to do so causes BASIC to signal "Subscript out of range" (ERR = 55), provided that subscript checking is enabled.
Note that you cannot create an array implicitly, then redimension the array with an executable DIM statement. The DIM statement must execute before any reference to the array.
An array name cannot appear in a declarative statement after the array has been implicitly declared by a reference. The following DECLARE statement is therefore illegal and causes BASIC to signal the compile-time error "illegal multiple definition of name NEW_ARRAY."
new_array (5,5,5) = 1 DECLARE LONG new_array (15,10,5) |
BASIC provides two built-in functions, LBOUND and UBOUND, that allow you to determine the lower and upper bounds, respectively, for any dimension in an array.
The following example sets up four variables that contain the lower and upper bounds of both dimensions of the array Sales_data. These variables represent the years and months for which there is sales data available. The two FOR...NEXT loops print all the sales information in the array, starting with the first year and month, and ending with the last year and month.
DECLARE Sales_data(1900 TO 1999, 1 TO 12) Month_start% = LBOUND (Sales_data, 2) Year_start% = LBOUND (Sales_data, 1) Month_end% = UBOUND (Sales_data, 2) Year_end% = UBOUND (Sales_data, 1) FOR Year% = Year_start% TO Year_end% FOR Month% = Month_start% TO Month_end% PRINT Sales_data(Year%, Month%) NEXT Month% NEXT Year% |
You cannot implicitly declare arrays with the LBOUND and UBOUND functions. These functions can be used only with arrays that have been previously declared. |
The following sections explain how to access and write to BASIC arrays with the LET and PRINT statements.
Previous | Next | Contents | Index |