Previous | Contents | Index |
The SELECT...CASE statement lets you specify an expression (the SELECT expression), any number of possible values (cases) for the SELECT expression, and a list of statements (a CASE block) for each case. The SELECT expression can be a numeric or string value. CASE values can be single or multiple values, one or more ranges of values, or relationships. When a match is found between the SELECT expression and a CASE value, the statements in the following CASE block are executed. Control is then transferred to the statement following the END SELECT statement.
In the following example, the CASE values appear to overlap; that is, the CASE value that tests for values greater than or equal to 0.5 also includes the values greater than or equal to 1.0. However, BASIC executes the statements associated with the first matching CASE statement and then transfers control to the statement following END SELECT. In this program, each range of values is tested before it overlaps in the next range. Because the compiler executes the first matching CASE statement, the overlapping values do not matter.
DECLARE REAL Stock_change INPUT "Please enter stock price change";Stock_change SELECT Stock_change CASE <= 0.5 PRINT "Don't sell yet." CASE <= 1.0 PRINT "Sell today." CASE ELSE PRINT "Sell NOW!" END SELECT END |
Please enter stock price change? 2.1 Sell NOW! |
If no match is found for any of the specified cases and there is no CASE ELSE block, BASIC transfers control to the statement following END SELECT without executing any of the statements in the SELECT block.
SELECT...CASE lets you use run-time expressions for both SELECT expressions and CASE values. The following example uses BASIC built-in string functions to examine command input:
! This program is a skeleton command processor. ! It recognizes three VAX BASIC Environment commands: ! ! SAVE ! SCRATCH ! OLD DECLARE INTEGER CONSTANT True = -1 DECLARE INTEGER CONSTANT False = 0 DECLARE STRING CONSTANT Null_input = "" !This is the null string. DECLARE STRING Command ! Main program logic starts here. Command_loop: WHILE True ! This loop executes until the user types only a ! carriage return in response to the prompt. PRINT PRINT "Please enter a command (uppercase only)." PRINT "Type a carriage return when finished." INPUT Command PRINT SELECT Command CASE Null_input ! If user types RETURN, ! exit from the loop GOTO Done ! and end the program. ! The next three cases use the SEG$ and LEN string functions. ! LEN returns the length of the typed string, and SEG$ searches ! the string literals ("SAVE", "SCRATCH", and "OLD") for a ! match up to that length. Note that if the user types an "S", ! it is interpreted as a SAVE command only because SAVE is the ! first case tested. CASE SEG$ ( "SAVE", 1%, LEN (Command) ) PRINT "That was a SAVE command." CASE SEG$ ( "SCRATCH", 1%, LEN (Command) ) PRINT "That was a SCRATCH command." CASE SEG$( "OLD", 1%, LEN (Command) ) PRINT "That was an OLD command." CASE ELSE PRINT "Invalid command, please try again." END SELECT NEXT Done: END |
This section describes the EXIT and ITERATE statements and shows their use with nested control structures.
The ITERATE and EXIT statements let you explicitly control loop execution. These statements can be used to transfer control to the top or bottom of a control structure.
You can use EXIT to transfer control out of any of these structures:
In the case of control structures, EXIT passes control to the first statement following the end of the control structure.
You can use ITERATE to explicitly reexecute a FOR...NEXT, WHILE...NEXT, or UNTIL...NEXT loop. EXIT and ITERATE statements can appear only within the code blocks you want to leave or reexecute.
Executing the ITERATE statement is equivalent to transferring control to the loop's NEXT statement. The termination test is still performed when the NEXT statement transfers control to the top of the loop. In addition, transferring control to the NEXT statement means that a FOR loop's control variable is incremented by the STEP value.
Supplying a label for every loop lets you state explicitly which loop to leave or reexecute. If you do not supply a label for the ITERATE statement, BASIC reexecutes the innermost active loop. For example, if an ITERATE statement (that does not specify a label) is executed in the innermost of three nested loops, only the innermost loop is reexecuted.
In contrast, labeling each loop and supplying a label argument to the ITERATE statement lets you reexecute any of the loops. A label name also helps document your code. Because you must use a label with EXIT and it is sometimes necessary to use a label with ITERATE, you should always label the structures you want to control with these statements.
The following example shows the use of both the EXIT and ITERATE statements. This program explicitly exits the loop if you type a carriage return in response to the prompt. If you type a string, the program prints the length of the string and explicitly reexecutes the loop.
DECLARE STRING User_string Read_loop: WHILE 1% = 1% LINPUT "Please type a string"; User_string IF User_string == "" THEN EXIT Read_loop ELSE PRINT "Length is ";LEN(User_string) ITERATE Read_loop END IF NEXT END |
In BASIC, a subroutine is a block of code accessed by a GOSUB or ON GOSUB statement. It must be in the same program unit as the statement that calls it. The RETURN statement in the subroutine returns control to the statement immediately following the GOSUB.
The first line of a subroutine can be any valid BASIC statement, including a REM statement. You do not have to transfer control to the first line of the subroutine. Instead, you can include several entry points into the same subroutine. You can also reference subroutines by using a GOSUB or ON GOSUB statement to another subroutine.
Variables and data in a subroutine are global to the program unit in
which the subroutine resides.
10.6.1 GOSUB and RETURN Statements
The GOSUB statement unconditionally transfers control to a line in a subroutine. The last statement in a subroutine is a RETURN statement, which returns control to the first statement after the calling GOSUB. A subroutine can contain more than one RETURN statement so you can return control conditionally, depending on a specified condition.
The following example first assigns a value of 5 to the variable A, then transfers control to the subroutine labeled Times_two. This subroutine replaces the value of A with A multiplied by 2. The subroutine's RETURN statement transfers control to the first PRINT statement, which displays the changed value. The program calls the subroutine two more times, with different values for A. Each time, the RETURN transfers control to the statement immediately following the corresponding GOSUB.
A = 5 GOSUB Times_two PRINT A A = 15 GOSUB Times_two PRINT A A = 25 GOSUB Times_two PRINT A GOTO Done Times_two: !This is the subroutine entry point A = A * 2 RETURN Done: END |
10 30 50 |
Note that BASIC signals "RETURN without GOSUB" if it
encounters a RETURN statement without first having encountered a GOSUB
or ON GOSUB statement.
10.6.2 ON...GOSUB...OTHERWISE Statement
The ON...GOSUB...OTHERWISE statement transfers control to one of several target subroutines depending on the value of a numeric expression. A RETURN statement returns control to the first statement after the calling ON GOSUB. A subroutine can contain more than one RETURN statement so that you can return control conditionally, depending on a specified condition.
BASIC tests the value of the integer expression. If the value is 1, control transfers to the first line number or label in the list; if the value is 2, control passes to the second line number or label, and so on. If the control variable's value is less than 1 or greater than the number of targets in the list, BASIC transfers control to the line number or label specified in the OTHERWISE clause. If you do not supply an OTHERWISE clause and the control variable's value is less than 1 or greater than the number of targets, BASIC signals "ON statement out of range (ERR=58)". For example:
INPUT "Please enter first integer value"; First_value% INPUT "Please enter second integer value"; Second_value% Choice: PRINT "Do you want to perform:" PRINT "1. Multiplication" PRINT "2. Division" PRINT "3. Exponentiation" INPUT Selection% ON Selection% GOSUB Mult, Div, Expon OTHERWISE Wrong GOTO Done Mult: Result% = First_value% * Second_value% PRINT Result% RETURN Div: Result% = First_value / Second_value% PRINT Result% RETURN Expon: Result% = First_value% ** Second_value% PRINT Result% RETURN Wrong: PRINT "Invalid selection" RETURN Done: END |
The following BASIC statements suspend program execution:
SLEEP
WAIT
These statements cause BASIC either to suspend program execution for a specified time or to wait a certain period of time for user input.
After execution of the last statement, a BASIC program automatically halts and closes all files. However, you can explicitly halt program execution by using one of the following statements:
STOP
END
The STOP statement does not close files. It can appear anywhere in a
program. The END statement closes files and must be the last statement
in a main program.
10.7.1 SLEEP Statement
The SLEEP statement suspends program execution for a specified number of seconds. The following program waits two minutes (120 seconds) after receiving the input string, and then prints it:
INPUT "Type a string of characters"; C$ SLEEP 120% PRINT C$ END |
The SLEEP statement is useful if you have a program that depends on
another program for data. Instead of constantly checking for a
condition, the SLEEP statement lets you check the condition at
specified intervals.
10.7.2 WAIT Statement
You use the WAIT statement only with terminal input statements such as INPUT, INPUT LINE, and LINPUT. For example, the following program prompts for input, then waits 30 seconds for your response. If the program does not receive input in the specified time, BASIC signals "Keyboard wait exhausted (ERR=15)" and exits the program.
WAIT 30% INPUT "You have 30 seconds to type your password"; PSW$ END |
The WAIT statement affects all subsequent INPUT, INPUT LINE, LINPUT, MAT INPUT, and MAT LINPUT statements. To disable a previously specified WAIT statement, use WAIT 0%.
In the following example, the first WAIT statement causes the first INPUT statement to wait 30 seconds for a response. The WAIT 0% statement disables this 30-second requirement for all subsequent INPUT statements.
WAIT 30% INPUT "You have 30 seconds to type your password"; PSW$ WAIT 0% INPUT "What directory do you want to go to"; DIR$ |
The STOP statement is a debugging tool that lets you check the flow of program logic. STOP suspends program execution but does not close files.
When BASIC executes a STOP statement, it signals "STOP at line <line-num>". If the program executes in the VAX BASIC Environment, BASIC prompts with the Ready command level prompt. In response, you can enter the following:
You use the STOP statement when debugging in immediate mode in the VAX BASIC Environment. For more information about immediate mode statements, see Chapter 2.
If you compile, link, and execute a program containing a STOP statement at DCL command level, BASIC displays a number sign (#) prompt when the STOP statement is encountered. At this point, you can enter:
The END statement marks the end of a main program. When BASIC executes an END statement, it closes all files and halts program execution.
The END statement is optional in BASIC programs. However, it is good programming practice to include it. The END statement must be the last statement in the main program.
If you run your program in the VAX BASIC Environment, the END statement returns you to BASIC command level. If you execute the program outside the VAX BASIC Environment, the END statement returns you to DCL command level.
A function is a single statement or group of statements that perform operations on operands and return the result to your program. BASIC has built-in functions that perform numeric and string operations, conversions, and date and time operations. This chapter describes only a selected group of built-in functions. For a complete description of all BASIC built-in functions, see the Compaq BASIC for OpenVMS Alpha and VAX Systems Reference Manual.
This chapter also describes user-defined functions. BASIC lets you define your own functions in two ways:
DEF function definitions are local to a program module, while external functions can be accessed by any program module. You create local functions with the DEF statement and optionally declare them with the DECLARE statement. You create external functions with the FUNCTION statement and declare them with the EXTERNAL statement. For more information about creating external functions with the FUNCTION statement, see Chapter 13.
Once you create and declare a function, you can invoke it like a
built-in function.
11.1 Built-In Functions
The functions described in this section let you perform sophisticated
manipulations of string and numeric data. BASIC also provides
algebraic, exponential, trigonometric, and randomizing mathematical
functions.
11.1.1 Numeric Functions
Numeric functions generally return a result of the same data type as the function's parameter. For example, if you pass a DOUBLE argument to any of the trigonometric functions, they return a DOUBLE result.
If the format of a BASIC function specifies an argument of a particular data type, BASIC converts the actual argument supplied to the specified data type. For example, if you supply an integer argument to a function that expects a floating-point number, BASIC converts the argument to a floating-point number. Floating-point arguments that are passed to integer functions are truncated, not rounded.
The following sections discuss the BASIC built-in numeric
functions.
11.1.1.1 ABS Function
The ABS function returns a floating-point number that equals the absolute value of a specified numeric expression. For example:
READ A,B DATA 10,-35.3 NEW_A = ABS(A) PRINT NEW_A; ABS(B) END |
10 35.3 |
The ABS function always returns a number of the default floating-point
data type.
11.1.1.2 INT and FIX Functions
The INT function returns the floating-point value of the largest integer less than or equal to a specified expression. The INT function always returns a number of the default floating-point type.
The FIX function truncates the value of a floating-point number at the decimal point. FIX always returns a number of the default floating-point type.
The following example shows the differences between the INT and FIX functions. Note that the value returned by FIX(-45.3) differs from the value returned by INT(-45.3).
PRINT INT(23.553); FIX(23.553) PRINT INT(3.1); FIX(3.1) PRINT INT(-45.3); FIX(-45.3) PRINT INT(-11); FIX(-11) END |
23 23 3 3 -46 -45 -11 -11 |
The SIN, COS, and TAN functions return the sine, cosine, and tangents of an angle in radians or degrees, depending on which angle clause you choose with the OPTION statement. If you supply a floating-point argument to the SIN, COS, and TAN functions, they return a number of the same floating-point type. If you supply an integer argument, they convert the argument to the default floating-point data type and return a floating-point number of that type.
The following example accepts an angle in degrees, converts the angle to radians, and prints the angle's sine, cosine, and tangent:
!CONVERT ANGLE (X) TO RADIANS, AND !FIND SIN, COS AND TAN PRINT "DEGREES", "RADIANS", "SINE", "COSINE","TANGENT" FOR I% = 0% TO 5% READ X LET Y = X * 2 * PI / 360 PRINT PRINT X ,Y ,SIN(Y) ,COS(Y) ,TAN(Y) NEXT I% DATA 0,10,20,30,360,45 END |
DEGREES RADIANS SINE COSINE TANGENT 0 0 0 1 0 10 .174533 .173648 .984808 .176327 20 .349066 .34202 .939693 .36397 30 .523599 .5 .866025 .57735 360 6.28319 .174846E-06 1 .174846E-06 45 .785398 .707107 .707107 1 |
As an angle approaches 90 degrees (PI/2 radians), 270 degrees (3*PI/2 radians), 450 degrees (5*PI/2 radians), and so on, the tangent of that angle approaches infinity. If your program tries to find the tangent of such an angle, BASIC signals "Division by 0" (ERR=61). |
The SQR function returns the square root of a number. For example:
PRINT SQR (2) |
1.41421 |
A logarithm is the exponent of some number (called a base). Common logarithms use the base 10. The common logarithm of a number n, for example, is the power to which 10 must be raised to equal n. For example, the common logarithm of 100 is 2, because 10 raised to the power 2 equals 100.
The LOG10 function returns a number's common logarithm. The following example calculates the common logarithms of all multiples of 10 from 10 to 100, inclusively:
FOR I% = 10% TO 100% STEP 10% PRINT LOG10(I%) NEXT I% END |
1 1.30103 1.47712 1.60206 1.69897 1.77815 1.8451 1.90309 1.95424 2 |
If you supply a floating-point argument to LOG10, the function returns
a floating-point number of the same data type. If you supply an integer
argument, LOG10 converts it to the default floating-point data type and
returns a value of that type.
11.1.1.6 EXP Function
The EXP function returns the value of e raised to a specified power. The following example prints the value of e and e raised to the second power:
READ A,B DATA 1,2 PRINT 'e RAISED TO THE POWER'; A; " EQUALS"; EXP(A) PRINT 'e RAISED TO THE POWER'; B; " EQUALS"; EXP(B) END |
e RAISED TO THE POWER 1 EQUALS 2.71828 e RAISED TO THE POWER 2 EQUALS 7.38906 |
If you supply a floating-point argument to EXP, the function returns a floating-point number of the same data type. If you supply an integer argument, EXP converts it to the default floating-point data type and returns a value of that type.
Previous | Next | Contents | Index |