Qbasic Wikibook
Qbasic Wikibook
< QBasic
Contents [hide]
1 Text Output
1.1 Print
1.2 1HELLO.BAS
1.3 Understanding 1HELLO.BAS
1.4 2HELLO.BAS
1.5 Commas and Semicolons in PRINT and CLS
1.6 3HELLO.BAS
1.7 Variables
1.8 4FACE.BAS
1.9 Locate statement
1.10 5FACE.BAS
1.11 Colors
1.12 Color by Number
1.13 Summary
2 Basic Input
2.1 6INPUT.BAS
3 Basic Math
3.1 Equation Setup
3.2 7MATH.BAS
3.3 Understanding 7MATH.BAS
3.4 8MATH.BAS
3.5 Understanding 8MATH.BAS
3.6 9TIP.BAS
3.7 Tip Calculator
3.8 10OROP.BAS
3.9 Parentheses and Order of Operations
3.10 Random Numbers
3.11 11RND.BAS
3.12 More on RND
4 Flow Control
4.1 Conditional execution
4.2 True or False
4.3 IF
4.4 IF...THEN...ELSE
4.5 13 ELSEIF
4.6 FOR...NEXT
4.7 14FOR.BAS
4.8 WHILE...WEND
4.9 15WHILE.BAS
4.10 DO...LOOP
4.11 12IF.BAS
4.12 SELECT CASE
5 Advanced Input
5.1 INKEY$
5.2 The keyboard buffer
5.3 Scancodes
6 Subroutines and Functions
6.1 Purpose
6.2 Procedure vs. Function
6.3 GOTO and GOSUB
6.4 ON ERROR
6.5 Declaring a subroutine
6.6 Declaring a function
7 Arrays and Types
7.1 Built-in Types
7.2 User-defined type
7.3 Array
7.4 Multidimensional array
7.5 Non-zero base
8 Appendix
8.1 Commands
8.1.1 ABS()
8.1.2 ACCESS
8.1.3 ASC()
8.1.4 ATN()
8.1.5 BEEP
8.1.6 CASE
8.1.7 CHAIN
8.1.8 CHDIR
8.1.9 CHR$()
8.1.10 CINT()
8.1.11 CIRCLE
8.1.12 CLEAR
8.1.13 CLOSE
8.1.14 CLS
8.1.15 COLOR
8.1.16 COMMON
8.1.17 CONST
8.1.18 DATA
8.1.19 DATE$
8.1.20 DIM
8.1.21 DO .. LOOP
8.1.22 DRAW
8.1.23 END
8.1.24 END IF
8.1.25 ENVIRON
8.1.26 EOF()
8.1.27 ERASE
8.1.28 ERROR
8.1.29 EXIT
8.1.30 FOR .. NEXT
8.1.31 GOSUB
8.1.32 IF
8.1.33 INCLUDE
8.1.34 INKEY$
8.1.35 INPUT
8.1.36 INPUT #
8.1.37 INSTR
8.1.38 LEFT$()
8.1.39 LET
8.1.40 LINE
8.1.41 LINE INPUT #
8.1.42 LOADIMAGE
8.1.43 LOOP
8.1.44 LPRINT
8.1.45 MID$
8.1.46 OPEN
8.1.47 PALETTE
8.1.48 READ
8.1.49 REM or '
8.1.50 RETURN
8.1.51 PLAY
8.1.52 PRINT
8.1.53 PSET
8.1.54 SCREEN
8.1.55 SEEK
8.1.56 SGN
8.1.57 SLEEP
8.1.58 SOUND
8.1.59 STR$
8.1.60 SYSTEM
8.1.61 THEN
8.1.62 TO
8.1.63 USING
8.1.64 VAL()
8.1.65 WHILE ... WEND
9 Authors
Text Output
Print [edit]
The text output command is PRINT. This is the command that we will be exploring through this section. PRINT takes a series of arguments. What
that means is that in QBasic, after typing PRINT (note, for a short cut, just type a question mark '?') a programmer types the things he wants
displayed and PRINT will display them. The first program will display the words "Hello World" on the screen.
1HELLO.BAS [edit]
First, copy everything (in this case, one line, but later programs will be much longer) into a text editor or into QBasic itself and save it as
'1HELLO.BAS'. Next open it in QBasic (if you are not already there) and press F5. This will run the program. A black screen with the words "Hello
World" in white on your left hand side of the screen should appear. This is your first QBasic program. Now, Press F5 again. Now there should be
2 lines saying "Hello World". This is because QBasic does not clear the screen every time a program is run. To change this we will use the
command CLS, which stands for CLear Screen. We will be looking at some other new concepts in the next program as well.
2HELLO.BAS [edit]
Addressing 2HELLO.BAS in line order, the first line prints "This line will be erased." to the screen, but in the second line, the CLS command
clears the screen immediately after, so it will not be seen (technically it flashes at the bottom form columns). "Hello Jupiter" should line up with '2'
at the bottom. More than one comma can be used in a row. In this example, after "Good Bye" two commas are used to move "For Now" over two
tab columns. "For Now" should line up with '3'.
My final statement on this topic is to play around with it. Try using commas and semicolons in a program.
3HELLO.BAS [edit]
CLS
hello$ = "Hello World"
number = 12
PRINT hello$, number
Variables [edit]
Variables are used to store information. They are like containers. You can put information in them and later change the information to something
else. In this first example they may not seem very useful but in the next section (Input) they will become very useful.
In this example we use two types of variables - string variables and numeric variables. A string variable holds words, a string of characters (a
character is a number, letter or symbol). In this case the characters are letters. A string variable is denoted by ending the name of the variable
with a dollar sign. The string variable in this program is hello$. What ever you set hello$ equal to will be displayed in the PRINT statement. The
numeric variable is number. Numeric variables do not have a special ending like string variables.
4FACE.BAS [edit]
CLS
LOCATE 14, 34 'position the left eye
PRINT "<=>" 'draw the left eye
LOCATE 14, 43 'position the right eye
PRINT "<=>" 'draw the right eye
LOCATE 16, 39 'position the nose
PRINT "o|o" 'draw the nose
LOCATE 18, 36 'position the mouth
PRINT "\_______/" 'draw the mouth
LOCATE 19, 42 'the bottom
PRINT "The Face by QBasic"
Locate allows you to position the cursor for the next piece of text output. Contrary to cartesian coordinates which read (X,Y), the locate statement
is LOCATE Y,X. In this case Y is the distance down from the top of the screen and X is the distance from the left side of the screen. The reason
that LOCATE does not follow the standard coordinate system is that it is not necessary to include the X portion, you can use the format LOCATE
Y which just specifies the line to start on.
5FACE.BAS [edit]
CLS
LOCATE 14, 34
COLOR 9
PRINT "<=>"
LOCATE 14, 43
PRINT "<=>"
COLOR 11
LOCATE 16, 39
PRINT "o|o"
COLOR 4
LOCATE 18, 36
PRINT "\_______/"
COLOR 20
LOCATE 19, 42
PRINT "U"
LOCATE 1, 1
COLOR 16, 1
PRINT "Hello World"
Colors [edit]
The program 5FACE.BAS is broken into sections to make it easier to read. This is an example of a good programming habit. Each three line
piece of code each piece of code specifies what color it's part of the face should be, where it should be and what it should look like. The order of
the position and the color is unimportant. The new statement COLOR allows you to change the color of the text. Once changed, all output will be
in the new color until COLOR or CLS is used. The format for the COLOR statement is:
COLOR [foreground]
or
COLOR [foreground],[background]
The colors are designated by numbers which will be discussed in the next section.
If you look carefully at this chart you can see that there are 8 main colors (0 through 7) and then those colors repeat, each in a lighter shade. You
may also notice that the colours act as a combination of binary values (where blue=1, green=2, red=4, etc.) This makes it much easier to
memorize the color scheme. Blinking colors are also available: at 16, the colors start over again with blinking black and extend through 31
(blinking white). However, the blinking option is not available for the background, only for the text (foreground).
It is possible to switch the blinking foreground text with an intense background, but this task is beyond the scope of the QBasic textbook, and may
not work when Windows displays the console in windowed mode.
Summary [edit]
In this section we looked at several methods to manipulate output. All centered around the PRINT statement. LOCATE and COLOR modified
where the text was displayed and how it looked. We used CLS to clear the screen. There was also a basic introduction to variables which will be
expanded upon in later sections.
The INPUT command is used to gather input from the user. This section will attempt to teach you how to gather input upon request from the user.
For real-time input, seeQBasic/Advanced Input.
or
Example:
INPUT "What is your name"; NAME$
INPUT "What is your age"; age
When an semicolon (;) is used between the text to the user and the variable, a question mark and a space are added to the output. When a
comma (,) is used no question mark is added.
If a string is specified (eg 'name$'), anything the user enters before pressing the 'return' key will be accepted. If a numeric variable (eg 'age') is
specified, the user must enter a number (if any non-numeric key is entered, the error message "Redo from start" will be output and the INPUT
command rerun)
6INPUT.BAS [edit]
CLS
INPUT "What is your name"; NAME$
PRINT "Hello, "; NAME$; "! ";
INPUT "How old are you"; age
PRINT "The user, "; NAME$; " is "; age; " years old"
Please note: In the PRINT command, the ';' function 'concatenates' (joins) the contents of the string variables with the text between the quotes ("
"). Note the use of spaces so that the final printed text reads properly.
If a numerical variables is specified within the PRINT command, an additional space is automatically added both before and after the number.
See also LINE INPUT command to read a line of text from a file (and place the result in a string variable) or to input a series of variables (in
which case any commas found will be treated as delimiters between fields).
A lot of programming is math. Don't let this scare you: a lot of the math is simple, but it's still math. In this section, we will look at doing some
basic math (the same stuff you learned in the 3rd grade) and manipulating numbers.
In QBasic an equation has a basic setup a right side and a left side. For instance X=5, as you can probably figure out, this sets the variable X to
5. But we can use variables on the right side too. Y=X*10 would set Y equal to 10 times X, in this situation, 50. In this next program I will show
several equations to give you a feel for math.
7MATH.BAS [edit]
CLS
e = a + b
PRINT a; "+"; b; "="; e
f = c * d
PRINT c; "*"; d; "="; f
g = b - c
PRINT b; "-"; c; "="; g
h = b / d
PRINT b; "/"; d; "="; h
i = INT(d)
PRINT "Remove the decimal from "; d; "="; i
The most important thing you can take away from this is the setup for math equations. I think you can figure out what all the symbols are and
what they do, but QBasic is picky about equations. For 'e=a+b', if you try 'a+b=e' it will not work. The final thing I would like to address in
7MATH.BAS is the INT() function. As far as vocabulary, a function is something that takes in a piece of information and gives you another piece
of information back. So PRINT, was a statement, and INT() is a function. The INT() function takes a number and truncates it's decimal, it does not
round. So INT(5.1) is 5 and INT(5.999) is still 5. If you want to round a number use CINT().
8MATH.BAS [edit]
CLS
INPUT "Enter a number: ", x
PRINT
x = x + 5
PRINT "X is now: "; x
x = x * x
PRINT "X is now: "; x
x = x / 5
PRINT "X is now: "; x
x = x - 4
PRINT "X is now: "; x
x = x / x
PRINT "X should be 1: "; x
8MATH.BAS shows one simple concept that is very important in programming, but impossible in math. The way that the computer calculates the
equation is it does all the math on the right side of the equation and then sticks it in the variable on the left side. So the equation x=x+5 makes
perfect sense, unlike math where it is a contradiction. Reassigning a value to a variable based on it's current value is common and a good way to
keep the number of variables down.
9TIP.BAS [edit]
CLS
INPUT "How much is your bill: ", bill
INPUT "What percent tip do you want to give: ", tip
PRINT
PRINT "The tip is"; tip; "$."
PRINT "Pay"; tip + bill; "$ total."
9TIP.BAS calculates your tip and total bill from the bill and percent tip you wish to give. The first three lines clear the screen and get the
information from the user. The fifth line changes the tip from a percent to the correct decimal by dividing by 100 (ex. 20%=.2 because 20/100=.2)
the next line takes that percent and turns it into a dollar value by multiplying the decimal value by the bill. So if your bill is $20.00 and you leave a
20% tip, it multiplies 20*.2 which is 4 or $4.00. The last three lines format the output.
This is a good example of a complete program. It collects information from the user, it processes the information and it gives the user feedback.
Also, the middle section of the program is a good example of variable conservation. This is subject that will take some practice to get used to. In
writing a program, if you use too many variables, it will become difficult to keep track of all of them. If you try and conserve too much, you code
may become difficult to understand.
You may notice that the program may print more than two decimal places if you enter a bill that is not an exact dollar value. As an exercise, try
modifying the program so that it only displays two decimal places - you can use the CINT() function or any other rounding method you intend to
use.
10OROP.BAS [edit]
'ORder of OPerations
CLS
a = 15
b = 10
c = 12.2
d = 1.618
10OROP.BAS is an example of order of operations and how parentheses can be used to manipulate it. I do not want to go into an indepth
explanation of the order of operations here. The best advice I can give is unless you are sure of the order of operations, use parentheses to make
sure the equation works how you want. All you need to know about parentheses is that the deepest nested parentheses calculate first. If you wish
to know more, there are plenty of algebra resources available. On that note, you may wish to brush up on algebra. While it is not necessary for
programming, it can help make programming easier and it can allow you to create more advanced programs.
Though we will not go into their use until the next section, I would like to discuss the generation of random numbers. QBasic has a random
number statement, RND, that generates a random decimal between 0 and 1. You can think of it as a random percent. At first, this may seem like
an odd way to generate random numbers. However, with a little math it is very easy to manipulate this to provide numbers in whatever range you
want.
The first step is to multiply RND by a number (the range you want). For instance 'RND*10'. This will return random numbers (decimal numbers)
between 0 and 10(both included). So, to pick a random number between zero and ten we would say '(RND*10)'
11RND.BAS [edit]
CLS
RANDOMIZE TIMER
To choose between two or more sections of the program to execute, the IF statement can be used. It is also possible to use the WHILE, DO
UNTIL and CASE statements. All of these control conditional execution by using a Boolean logic 'test', the result of which is either TRUE or
FALSE. To repeat a section of code for a set number of times, the FOR statement is used.
The IF test can be executed in a single line, however it can also be used like the others to control a block of code.
Boolean logic is a test that yields one of only two possible results, true or false. The tests are always mathematical in nature .. when two
characters (or strings) are 'compared' it is their ASCII codes that are used (thus a < b and b < A).
The comparison operators used in qbasic are: = true if two variables are equal < true if the first is less than the second =< true if the first is less
than or equal to the second > true if the first is greater than the second >= true if the first is greater than or equal to the second <> true if the two
are unequal
Multiple tests can be linked together in the comparison, using the 'AND', 'OR' and 'NOT' operators. We will cover exactly what these mean later
on, but you probably understand the first two already.
IF [edit]
One of the most useful statements in QBasic is the IF statement. It allows you to choose what your program will do depending on the conditions
you give it. The next few programs will be taking a look at ways to use the IF statement.
The single line IF is the simplest example. To execute a block of code, the END IF is used
IF [conditional] THEN
[do this]
[and do this]
...
[and also do this]
END IF
IF...THEN...ELSE [edit]
To choose between two different code blocks, the ELSE statement is used.
IF [conditional] THEN
[do this]
..
[and do this]
ELSE
[do that]
..
[and also that]
END IF
13 ELSEIF [edit]
As an alternative to starting an entirely new IF THEN ELSE statement sequence. You can follow the THEN statement(s) with ELSEIF
[conditional] THEN. This does not create a new level of nesting.
IF [conditional] THEN
[do this]
..
[and do this]
[do that]
..
[and also that]
ELSE
END IF
FOR...NEXT [edit]
<increment> may be + or - and is optional. If omitted the default is +1. The code contained within the FOR loop will always be executed at least
once because it is only at the 'NEXT' statement that the value of the variable is checked against the end value.
When the NEXT statement executes, the variable is modified by STEP value and compared against the end value. If the variable has not yet
exceeded the end value, control is returned to the line following the FOR.
You can exit a FOR loop early with the EXIT FOR command.
14FOR.BAS [edit]
CLS
RANDOMIZE TIMER
FOR count = 1 TO 5
INPUT "Pick a number between 1 and 20: ", answer
IF answer = num THEN PRINT "You win after";count;"guesses!": END
NEXT
PRINT "You lose"
WHILE...WEND [edit]
If the condition is true, the code following the WHILE is executed. When the WEND command is executed, it returns control to the WHILE
statement (where the condition is tested again). When the condition evaluates to FALSE, control is passed to the statement following the WEND.
15WHILE.BAS [edit]
In the example above, you see a press any key prompt that waits until the user presses a key. (The INKEY$ feature will be described
under Advanced Input.)
DO...LOOP [edit]
DO
[this]
..
[and this]
LOOP WHILE <condition is true> / LOOP UNTIL <condition is true>
The DO...LOOP construct is a more advanced of the WHILE loop - as with other flow control blocks, it is marked by DO and LOOP to denote the
boundaries.
DO
a$ = INKEY$
LOOP WHILE a$=""
As an alternative, you can instead replace WHILE with UNTIL have the loop continue until a specific condition is met:
DO
x=x+1
LOOP UNTIL x >= 10
In some versions of BASIC the UNTIL or WHILE condition can follow the DO statement rather than the LOOP statement (pre-test) as apposed to
the above shown (post-test).
12IF.BAS [edit]
CLS
RANDOMIZE TIMER
The select statement is a substitute for repeated use of IF statements. The <variable expression> is evaluated and compared against each CASE
<value> in turn. When a CASE <value> is found to match, the [do this] code following is executed. If an EXIT CASE is executed, control passes
to the line following the END SELECT, otherwise the next CASE <value> is checked. If no matches are found, the CASE ELSE is executed. Note
that <value> may be a number, character or string or logical expression (eg '>0', '<>1'). Note also that multiple CASE matches may be found and
executed (so, for example, if two CASE <values> are 'CASE >1' and 'CASE >10', a <variable expression> that evaluates to 11 (or more) will
result in both CASE >1 and CASE >10 being executed)
CLS
PRINT "WELCOME"
PRINT "I HAVE AN ANSWER FOR ANY OF YOUR QUESTIONS"
INPUT "WRITE YOUR QUESTION AND I'LL GIVE YOU AN ANSWER ", question$
10 RANDOMIZE TIMER
PRINT
answer=INT(RND*10+1)
SELECT CASE answer
If a parameter would be covered by more than one case statement, the first option will take priority.
INKEY$ [edit]
Getting real time information from the user is a little more difficult. To do so, we will use the INKEY$ command, which checks to see if a user
typed a key and provides the keypress to the program.
DO
LET k$ = INKEY$
LOOP UNTIL k$ <> ""
SELECT CASE k$
CASE "q"
QuitProgram
CASE "c"
MakeCircle
CASE "s"
MakeSquare
END SELECT
The first part is the DO-LOOP which constantly polls INKEY$ for a return value. In the basic use, INKEY$ returns an empty string if no keys are
being pressed and continues with the program. Once a key is pressed, INKEY$ will return that key immediately.
While the INKEY$ command looks like it returns the key currently being pressed, this is not the case. It is used by the program to answer the
question, "What is IN the KEYboard buffer?" To understand this you will need to understand what a basic buffer is and why it is used.
In older systems (not necessarily the IBM PC) a single chip processed keyboard input, and controlled the LED lights for caps lock and number
lock. Because a computer does many things at once (e.g., take input from the mouse, crunch numbers, call subroutines, display new information
on the screen), it needs to be able to remember what was pressed on the keyboard while it is busy. This chip contained some memory (called a
buffer) that allow keeping track of a limited number of keypresses.
Within the Dos platform under IBM PCs, the hardware has changed slightly. Instead of a hardware buffer, pressing or releasing a key will
interrupt the running program to add a keystroke to a software buffer located in the BIOS. This procedure is usually unnoticed by the user and
has minimal impact on system performance. However, this buffer allows for 15 characters - attempting to overflow it when the computer is busy
will cause a short beep and drop any further characters.
The INKEY$ command uses this buffer as a FIFO (First In First Out) buffer. As an example let's say you have a game that has a bouncing ball on
the screen and a paddle at the bottom. The computer program constantly has to update the screen to show the movement of the ball. While it
does this the program passes by an INKEY$ command to see what value is returned. If the user has pressed a key since the last time the
command was invoked it will return that key. Let's say the ball is moving over to the right and the user needs to press the "R" key to tell the
program to move the paddle right. Since the program is busy moving the ball and updating the screen, it does not instantaneously notice that the
user has pressed the key. Instead, the key press is stored in the keyboard buffer, and retrieved a few milliseconds (or microseconds) later when
the INKEY$ command is used.
In many programs (as above), INKEY$ will appear nested in a loop. It is requested over and over again. This allows the program to get user input
one character at a time. Using our example above, the user may need to press R over and over again until the paddle is under the ball. On the
other hand, the user may press R too many times and need to press L to move it left. Because the INKEY$ command is using a FIFO buffer it will
always retrieve the keys pressed in the same order as they where typed.
In summary, the INKEY$ command will always return and remove the first character in the keyboard buffer. Generally speaking, it is used over
and over to retrieve every key that has been pressed, and to allow a user to interact with a program in a close approximation to "real time." If
there is no key in the keyboard buffer, INKEY$ it will return an empty string (no character).
Scancodes [edit]
Some keypresses are not associated with an ASCII character. When one of these keys is pressed, INKEY$ returns a string with two characters =
the first character is a null (ASCII code 0), and the second is the raw scan code for the keyboard. A full listing of the scancodes can be found
within the QBASIC help file - you can also determine the scan codes by examining the results of INKEY$ as you press those keys in question.
Note:
Some keys cannot be directly detected by INKEY$.
Purpose [edit]
Subroutines and functions are ways to break up your code into a reusable form. They allow the programmer to do a large set of operations just
by calling the appropriate procedure or function. For example, lets say you need to PRINT a lot of lines, such as instructions. One way to do this
is to just enter all your PRINT commands directly into where you need them. At some point, you may want to move the PRINT commands, or you
may use the exact set of PRINTs elsewhere in the program. To move or change all of the PRINT commands would be quite a hassle. A simpler
way would be to create a procedure and enter all of the PRINT commands there; then, when you need to execute the commands, you may
simply call your procedure and it will execute each line in its body.
A procedure DOES something and does not return anything for the programmer. For example, a procedure might be used to set the screen
mode and palette.
A function does something and RETURNS a value. For example, if you need to find the average of two values, you might write a function that
takes in two numbers and returns the average.
The GOTO and GOSUB statements were the original methods by which functions were created. They were the most common on older basic
implementations and are kept around for compatibility reasons; however, their use is not recommended in other programming languages or in
large scale projects.
These two commands depend on labels, which come in one of two forms. The first and older form involves writing line numbers at the beginning
of each line (usually in increments of 10). The newer method looks similar to other programming languages, which is a single word followed by a
colon.
The GOTO statement is simple; it moves the execution point to a given label:
The GOSUB statement transfers control to a given label, and is paired with a corresponding RETURN statement.
ON ERROR [edit]
The ON ERROR allows you to define an error handler for your program; when an error occurs, it immediately jumps to the given label. The
control returns once the program reaches a RESUME statement, which can either return control to the same point, the next statement, or any
other desired label.
Within Qbasic, the error handler cannot be located within any subroutines. As such, any error checking or flags will have to be handled through
the use of variables that are shared with the main module.
Note:
While the QBasic documentation states ON ERROR RESUME NEXT is a
valid statement, this is incorrect.
NOTE: If your error handling routine does not have a "resume" statement in it (IOW you try to do it all with gotos) error handling will only work
once - the next "on error" will be ignored and the program ends as if you had no "on error" statement at all. This problem does not seem to be
mentioned in any of the documentation. It took me three hours to figure out why two nearly identical program portions acted so differently.
A superior method of declaring a subroutine is using the SUB statement block. Under the QBasic IDE, doing so moves the SUB block to it's own
section in the window to prevent accidental deletion of the module, and allows the easier organization of the program code.
Calling a function is as simple as writing the name of the function (passing any required parameters.) If you want, you can use the CALL
statement to indicate to other programmers that it is a subroutine.
Parameters passed into subroutines are passed by 'reference' i.e. whilst they may take on a new name within the SUB any changes that are
made to the values are 'reflected back' into the originals. All other variables used within the SUB are discarded when the END SUB is reached (or
an EXIT SUB is executed), except as below :-
To 'preserve' the values of variables used within the SUB for re-use on the next CALL, use the STATIC keyword at the end.
If you need access to a variable (that has not been passed as a parameter), use the SHARED keyword to define each at the start of the
subroutine (a SHARED variable retains it's name).
A function is a form of subroutine that returns a value. Everything that applies in defining a subroutine also applies to a function. Within the
function, the return value is created by using the function name as a variable - the return value is then passed to the calling expression.
Functions are declared in the same way as variables - it returns the variable type it's defined to return, in the same way variables are defined to
contain their specified type. By default, it is a number, but appending a dollar sign indicates that it is returning a string.
Functions can only be called within an expression; unlike subroutines, they are not a standalone statement.
QBasic has five built-in types: INTEGER (%), LONG(&) integer, SINGLE(!) float, DOUBLE(#) float and STRING($).
Implicit declaration is by adding the type character to the end of the variable name (%, &, !, #, $). See QBasic/Basic math for more.
If you do not use either implicit or explicit declaration, QBASIC interpreter assumes INTEGER type.
To do:
Make this example more suitable
for textbook usage.
A user defined type allows you to create your own data structures. Please note that custom types are similiar to arrays.
TYPE playertype
NAME AS STRING
score AS INTEGER
END TYPE
You can then declare variables under this type, and access them:
This above example shows how a custom type can be used for maintaining data, say on a player who plays a game.
Array [edit]
An array is a collection of values stored in a single variable. Unless you DIM them, they are limited to 10 elements on each dimension.
By default, arrays in QBasic are static in size and cannot be changed later in the program. Code that will set up this type of array is as follows:
DIM myArray(10) AS TYPE
TYPE can be any of the built in QBasic or user-defined type. If this is not specified, the array takes the default type for the variable.
By issuing the Meta Command '$DYNAMIC at the beginning of your program you can cause your arrays to be dynamic:
' $DYNAMIC
DIM myDynamicArray(5) AS INTEGER
REDIM myDynamicArray(10) AS INTEGER
An array isn't restricted to one dimension - it's possible to declare an array to accept two parameters in order to represent a grid of values.
You cannot use the REDIM statement to change the number of dimensions on the array, even with dynamic allocation.
In most languages, arrays start at the value 0, and count up. In basic, it's possible to index arrays so that they start at any value, and finish at any
other value.
DIM deltas(-5 TO 5)
You can change the default lower bound with the OPTION BASE statement.
Appendix [edit]
Commands [edit]
ABS() [edit]
Returns the 'absolute' value of the expression, turning a negative to a positive (e.g. -4 to 4)
PRINT ABS(54.345) 'This will print the value ABS now as it is (54.345)
ACCESS [edit]
This sets the access of a file that has been declared into the program. There are three settings that the programmer can set. These are:
ASC() [edit]
Prints the ASCII code number of the character found within the brackets. If the programmer put in a string into brackets, only the first character of
the string will be shown.
ATN() [edit]
ATN(expression)
Part of the inbuilt trigonometry functions. An expression that evaluates to a numeric vale is converted to it's Arc-Tangent.
angle = ATN( B )
angle2 = ATN( 23 / 34 )
BEEP [edit]
BEEP
The BIOS on the motherboard is instructed to emit a "Beep" sound from the PC 'speaker'. See also SOUND and PLAY.
CASE [edit]
Use this when using multiple values in your program and assigning them separate paths. This is an example of a program with no CASE
commands that assigns different paths to values:
CHAIN [edit]
This 'calls' (transfers execution) to another program (typically another .bas file, a command (.bat or .cmd) script or an executable (.com, .exe) ).
Values may be passed directly in the invoking command (to files accepting command line parameters). Values may be passed to another basic
script by using the 'COMMON' statement before the CHAIN command.
Control returns to the basic interpreter when the 'chained' program terminates.
CHDIR [edit]
This is used for changing a directory. Used in conjunction with MKDIR and RMDIR. The directory name is declared exactly like in DOS PROMPT.
For example:
To use this command, the programmer will have to know how MS DOS and COMMAND PROMPT work.
CHR$() [edit]
Often used to 'load' characters into string variables when that character cannot be typed (e.g. the Esc key or the F{n} (Function Keys) or
characters that would be 'recognised' and acted upon by QBASIC interpreter (eg ", the double quote). Here is a list of some character codes :-
CINT() [edit]
PRINT CINT(4573.73994596)
4574
CIRCLE [edit]
CIRCLE ([X Coordinate], [Y Coordinate]), [Radius], [Colour]
Lets the programmer display a circle. Like all graphics commands, it must be used with the SCREEN command.
CLEAR [edit]
CLEAR
Resets all variables, strings, arrays and closes all files. The reset command on QBasic.
CLOSE [edit]
CLOSE
CLOSE #2
Closes only the file opened as data stream 2. Other files remain open
CLS [edit]
CLS
Clears the active screen. Erases all text, graphics, resets the cursor to the upper left (1,1), and also applies the current background color (this
has to be set using the COLOR command) to the whole screen.
COLOR [edit]
This lets you change the colour of the text and background used when next 'printing' to the current output window. It can be done like this:
COLOR 14, 01
PRINT "Yellow on Blue"
These values are the numbers that you put in the COLOR command.
Note Only screen modes 0, 7, 8, 9, 10 support a background color. To 're-paint' the whole screen in a background colour, use the CLS command.
COMMON [edit]
Declares a variable as 'global' which allows it's value to be accessed across multiple QBasic programs / scripts (see also the CHAIN command)
COMMON SHARED [variablename]
Each program that declares 'variablename' as COMMON will share the same value.
NOTE. All COMMON statements must appear at the start of the program (i.e. before any executable statements).
CONST [edit]
For example :-
CONST PI = 3.14159265
CONST PI2 = 2 * PI
PI must be assigned a value before it is used to calculate PI2. Typically all CONST are declared at the beginning of a program.
DATA [edit]
DATA [constant]
Use in conjunction with the READ and RESTORE command. Mostly used in programs dealing with graphics, this command lets QBasic read a
large number of constants. The READ command accesses the data while the RESTORE command "refreshes" the data, allowing it to be used
again.
DATE$ [edit]
A system variable that always contains the current date as a string in mm-dd-yyyy format. Use it like this:
a$ = DATE$
DIM [edit]
This is used to declare an array (early versions of Basic required all variables to be defined, not just arrays greater than 10)
The Array name can be of any type (Integer, Double, String etc). If not declared, single precision floating point is assumed. Strings can be
'declared' using $ sign (Integers with the '%' sign). The QBASIC interpreter tolerates numeric arrays of up to 10 count without these needing to be
declared.
NOTE Early versions of QBasic did not explicitly set the contents of an array to zero (see CLEAR command)
DIM table%(100,2)
DIM form$(5)
DO .. LOOP [edit]
DO
[program]
LOOP UNTIL [test condition becomes TRUE]
Used to create a loop in the program. The [condition] is tested only after the [program] code is executed for the first time (see also WHILE). For
example:
num$ = 1
sum$ = 0
DO
sum$ = 2 * num$
PRINT sum$
num$ = num$ + 1
LOOP UNTIL num$ = 13
This program outputs the Two Times Tables up to 12. The Reason why we put 13 is that the program stops at that point and does not continue
the loop. If we put LOOP UNTIL num$ = 12 the last output on the screen would be "22".
DRAW [edit]
Used to draw a straight line from the current 'cursor' position in the current colour. DRAW defines the direction (up, down etc.) and the length of
the line (in pixels). For example:-
SCREEN 7
PSET (50, 50), 4
DRAW "u50 r50 d50 l50"
U = Up E = Upper-right
D = Down F = Lower-right
L = Left G = Lower-left
R = Right H = Upper-left
The drawing 'cursor' is left at the position where the line ends. u50 draws from 50,50 upwards ending at 50,0 r50 draws from 50,0 to the right,
ending at 100,0 d50 draws from 100,0 downwards, ending at 100,50 l50 draws from 100,50 to the left, ending at 50,50
The example shown will thus draw a red 'wire frame' square.
Note: Pixels are square. The diagonal from 0,0 to 100,100 will be 100 * root(2) pixels long (i.e. 141)
END [edit]
END
Signifies the end of the program. When QBasic sees this command it usually comes up with a statement saying: "Press Any Key to Continue".
END IF [edit]
END IF
ENVIRON [edit]
NOTE: If you are running QBasic on a Windows system, you wont be able to use this command.
This command lets you set an environment variable for the duration of the session. On exit from the QBasic.exe interpreter, the variables revert
to their original values.
EOF() [edit]
This checks if there are still more data values to be read from the file specified in (). EOF() returns a boolean / binary value, a one or zero. 0 if the
end of file has not been reached, 1 if the last value in the file has been read (see also LINE INPUT)
Note that, since the INPUT is executed before UNITIL is reached, File.txt must contain at least one line of text - if the file is empty, you will
receive an 'ERROR (62) Input past end of file'.
ERASE [edit]
ERROR [edit]
System variable holding a numeric value relating to the processing of the previous line of code. If the line completed without error, ERROR is set
to 0. If the line failed, ERROR is set to one of the values shown below. Most commonly used to redirect program flow to error handling code as
in :-
If ERROR is non=zero, program flow jumps to the line number or label specified. If ERROR is zero, program flow continues with the next line
below.
To manually test your program and check to see if the error handling routine runs OK, ERROR can be set manually :-
ERROR [number]
Note that ERROR is set when execution fails, not when the code is 'read' - so, for example, a 'divide by 0' will be found before the result is
assigned to a non-existent array variable or written to a non-existent file.
EXIT [edit]
Allows the immediate exit from a subroutine or a loop, without processing the rest of that subroutine or loop code
EXIT DEF
EXIT DO
Exits from a DO loop, execution continues with the command directly after the LOOP command
EXIT FOR
Exits from a FOR loop, execution continues with the command directly after the NEXT command
EXIT FUNCTION
Exits a FUNCTION procedure, execution continues with the command directly after the function call
EXIT SUB
The variable is set to the [start value], then program code is executed and at the Next statement the variable is incremented by 1 (or by the STEP
value, if any is specified). The resulting value is compared to the [end value] and if not equal program flow returns to the line following the FOR
statement.
For example:
Care must be taken when using STEP, since it is quite possible to step past the (end value) with the result that the FOR loop will run 'for ever'
(i.e. until the user aborts the interpreter or an error occurs), for example :-
200 198 196 194 192 ... 0 -2 -4 ... -32768 ERROR overflow
GOSUB [edit]
Command processing jumps to the subroutine specified. When the RETURN command is encountered, processing returns to this point and
continues with the line below the GOSUB.
IF [edit]
Compares variables or strings. For example, if you wanted to examine whether or not a user-entered password was the correct password, you
might enter:
IF a$ = "password" THEN PRINT "Password Correct"
Where a$ is the user entered password. Some operators include:
"="- equal to
"<"- less than (only used when variable or string is a number value)
">"- greater than (only used when variable or string is a number value)
"<>"- does not equal
"<="- less than or equal to (only used when variable or string is a number value)
">="- greater than or equal to (only used when variable or string is a number value)
One can also preform actions to number values then compare them to other strings or variables using the if command, such as in the below
examples:
IF a+5 = 15 THEN PRINT "Correct"
IF a*6 = b*8 THEN PRINT "Correct"
INCLUDE [edit]
QBasic supports the use of include files via the $INCLUDE directive:
'$INCLUDE: 'foobar.bi'
Note that the include directive is prefixed with an apostrophe, dollar, and that the name of the file for inclusion is enclosed in single quotation
mark symbols.
INKEY$ [edit]
[variable] = INKEY$
This is used when you want a program to function with key input from the keyboard. Look at this example on how this works:
a$ = INKEY$
PRINT "Press Esc to Exit"
END IF a$ = CHR$(27)
You can use this in conjunction with the CHR$ command or type the letter (e.g. A).
INPUT [edit]
Displays the String Literal, if a semi colon follows the string literal, a question mark is displayed, and the users input until they hit return is entered
into the variable. The variable can be a string or numeric. If a user attempts to enter a string for a numeric variable, the program will ask for the
input again. The String Literal is option. If the string literal is used, a comma (,) or semicolon (;) is necessary.
INPUT # [edit]
Reads a string / value from the specified file stream (see also LINE INPUT #)
Reads 4 values from the file that is OPEN as #1. a$ is assigned all text until a ',' (comma) or end of line is reached, b$ the next segment of text,
then two numeric values are interpreted and assigned to n and m.
Note that, within the file, numbers can be separated by 'anything' - so, if a number is not found (for 'n' or 'm') on the current 'line' of the file, the
rest of the file will be searched until a number is found. Input is then left 'pointing' at the position in the file after the last number required to satisfy
the input statement (see also 'seek #' command)
INSTR [edit]
Returns the character position of the start of the first occurrance of Find$ within Search$, starting at character position 'start%' in Search$. If
Find$ is not found, 0 is returned. start% is optional (defaul = 1, the first character of Seach$)
returns 4
LEFT$() [edit]
A$ = LEFT$(B$,N)
A$ is set to the left most characters of B$ ending at the Nth character.
LET [edit]
Early versions of the QBasic.exe command interpreter required use of the 'LET' command to assign values to variables. Later versions did not.
LET N = 227 / 99
LET A$="a line of simple text"
is equliavent to :-
N = 227 / 99
A$="a line of simple text"
LINE [edit]
Used for drawing lines in QBasic. The first X and Y are used as coordinates for the beginning of the line and the second set are used for
coordinating were the end of the line is. You must put a SCREEN command at the beginning of the program to make it work.
Note. When in SCREEN 13, the Colour Number == the Palette number
Reads a complete line as text characters from the file OPEN as stream #1 and places it in a$.
To find the 'end of line', the QBasic interpreter seaches for the 'Carriage Return' + 'Line Feed' (0x0D, 0x0A) characters. When reading text files
created on UNIX/LINUX systems (where the 'Line feed' 0x0A is used on it's own to signify 'end of line'), LINE INPUT will not recognise the 'end of
line' and will continue to input until the end of file is reached. For files exceeding 2k characters, the result is an "Out of String Space" Error as a$
'overflows'. One solution is to use a text editor able to handle UNIX files to open and 'save as' before atempting to process the file using QBasic.
LOADIMAGE [edit]
_LOADIMAGE("image.jpg")
Shows an image. Must be used with the commands SCREEN, _NEWIMAGE and _PUTIMAGE.
Example:
DIM rabbit AS LONG SCREEN _NEWIMAGE(800, 600, 32) rabbit = _LOADIMAGE("rabbit.jpg") _PUTIMAGE (100,100), rabbit
LOOP [edit]
DO
[Program]
LOOP UNTIL [condition]
Used to create a loop in the program. This command checks the condition after the loop has started. This is used in conjunction with the DO
command.
LPRINT [edit]
Prints out text to a printer. The LPRINT command expects a printer to be connected to the LPT1(PRN) port. If a printer is not connected to LPT1,
QBasic displays a "Device fault" error message.
If your printer is connected to a COM port instead, use the MS-DOS MODE command to redirect printing from LPT1 to COMx (for example, to
redirect to COM1, use the following command:
MODE LPT1=COM1
If you need to cancel the redirection when finished, use the following command:
MODE LPT1
MID$ [edit]
a$=MID$(string$,start%[,length%])
MID$(string$,start%[,length%])=b$
In the first use, a$ is set to the substring taken from string$ strating with character start% taking Length% characters. If length% is omitted, the
rest of the line (i.e. start% and all the characters to the right) are taken.
In the second use, length% characters of string$ are replaced by b$ starting at start%. If length% is omitted, the rest of the line is replaced (i.e.
start% and all the chracters to the right)
OPEN [edit]
This opens a file. You have to give the DOS file name, for example:
Opens the existing file data.txt for reading as data stream #1. Since no path is specified, the file must be in the same folder as the QBasic.exe - if
not, processing halts with a 'file not found' error
Opens an empty file named RUN.LOG in the C:\TEMP folder for writing data stream #2. Any existing file of the same name is replaced.
PALETTE [edit]
For VGA (SCREEN mode 13) only, sets the Palette entry to a new RGB color. The palette number must be in the range 1-256. The required
colour is a LONG integer created from the sum of (required Blue * 65536) + (required Green * 256) + required Red.
READ [edit]
READ [Variable]
Used in conjunction with the DATA command, this command lets QBasic read data. This is mostly used when dealing with large quantities of
data like bitmaps.
REM {comments}
' {comments}
When the interpreter encounters REM or " ' " (a single quote) at the start of a line, the rest of the line is ignored
RETURN [edit]
RETURN
PLAY [edit]
Used to play notes and a score in QBasic on a computer equipped with a MIDI sound-card (all modern computer motherboards with built-in
sound support MIDI). The tones are indicated by letters A through G. Accidentals are indicated with a "+" or "#" (for sharp) or "-" (for flat)
immediately after the note letter. See this example:
Whitespaces are ignored inside the string expression. There are also codes that set the duration, octave and tempo. They are all case-
insensitive. PLAY executes the commands or notes the order in which they appear in the string. Any indicators that change the properties are
effective for the notes following that indicator.
Ln Sets the duration (length) of the notes. The variable n does not indicate an actual duration
amount but rather a note type; L1 - whole note, L2 - half note, L4 - quarter note, etc.
(L8, L16, L32, L64, ...). By default, n = 4.
For triplets and quintets, use L3, L6, L12, ... and L5, L10, L20, ... series respectively.
The shorthand notation of length is also provided for a note. For example, "L4 CDE L8 FG L4 AB"
can be shortened to "L4 CDE F8G8 AB". F and G play as eighth notes while others play as quarter notes.
On Sets the current octave. Valid values for n are 0 through 6. An octave begins with C and ends with B.
Remember that C- is equivalent to B.
< > Changes the current octave respectively down or up one level.
Nn Plays a specified note in the seven-octave range. Valid values are from 0 to 84. (0 is a pause.)
Cannot use with sharp and flat. Cannot use with the shorthand notation neither.
MN Stand for Music Normal. Note duration is 7/8ths of the length indicated by Ln. It is the default mode.
ML Stand for Music Legato. Note duration is full length of that indicated by Ln.
MS Stand for Music Staccato. Note duration is 3/4ths of the length indicated by Ln.
Pn Causes a silence (pause) for the length of note indicated (same as Ln).
Tn Sets the number of "L4"s per minute (tempo). Valid values are from 32 to 255. The default value is T120.
. When placed after a note, it causes the duration of the note to be 3/2 of the set duration.
This is how to get "dotted" notes. "L4 C#." would play C sharp as a dotted quarter note.
It can be used for a pause as well.
MB MF Stand for Music Background and Music Foreground. MB places a maximum of 32 notes in the music buffer
and plays them while executing other statements. Works very well for games.
MF switches the PLAY mode back to normal. Default is MF.
PRINT [edit]
Displays text to the screen. The Argument can be a string literal, a string variable, a numeric literal or a numeric variable. All arguments are
optional.
PSET [edit]
This command displays pixels, either one at a time or a group of them at once. For the command to work, the program must have a SCREEN
command in it.
SCREEN [edit]
This command is used for displaying graphics on the screen. There are ten main types of screen modes that can be used in QBasic depending
on the resolution that you want. Here is a list of what screen modes you can choose from:
SCREEN 0: Textmode, cannot be used for graphics. This the screen mode that text based programs run on.
SCREEN 10: 640 x 350 Resolution. Two Colours (Black and White)
Note. In SCREEN 13 you have a colour Palette of 256 colours. The PALETTE is pre-set by Windows however you can change the RGB values
using the PALETTE command.
SEEK [edit]
SGN [edit]
SLEEP [n]
SOUND [edit]
Unlike the BEEP command, this produces a sound from the PC speakers that is of a variable frequency and duration. The frequency is measured
in Hertz and has a range from 37 to 32767. Put in one of these numbers in the frequency section. The duration is clock ticks that is defaulted at
18.2 ticks per second.
STR$ [edit]
The numeric value is converted into text characters and placed into A$. Used to convert numbers into a text string.
WARNING. If the result is positive, a leading 'space' is added (STR$(123) = " 123" and not "123" as might be expected). If the result is negative,
instead of a space you get a '-' (minus sign), i.e. STR$(-123) = "-123" and not " -123" as might be expected from the positive behaviour.
See also CHR$ for converting an ascii value into a string character.
See also LEFT$, MID$, RIGHT$ for extracting sub-strings from a line of text.
SYSTEM [edit]
SYSTEM
The .bas exits, the QBasic.exe interpreter is closed and 'control' passes to the Command Window c:\ prompt (or next line of a calling .cmd script
etc.).
THEN [edit]
Used in conjunction with the GOTO or IF condition commands. It tells the computer what to do if a certain condition has been met.
TO [edit]
This example will print all numbers from 400 to 500. Instead of declaring all values separately, we can get them all declared in one go.
USING [edit]
USING "format";
Used to format the output of data from PRINT commands. Normally, the QBasic interpreter will print a number as 8 characters with as many
leading spaces as necessary. To change this behavour, the USING command can be used to format the output. For example ..
IF n > 99 THEN PRINT #1, USING "###"; n; ELSE IF n > 9 THEN PRINT #1, USING "0##"; n; ELSE PRINT #1, USING "00#"; n;
.. will output n from 0 to 999 with leading zeros. Note the ';' after the n. This means 'don't start a new line' and results in the next PRINT #1 adding
data directly after the comma (',') Qbasic automatically inserts instead of a line line.
VAL() [edit]
name=VAL([variable$])
Converts the [variable string] contents into a numeric value so it can be used in calculations. If (name) is an INTEGER type, the VAL is rounded
down. See also STR$.
A$ = "2 + 3"
B = VAL(A$)
PRINT A$ is B
2 + 3 is 5
The condition is tested and if true (or NOT true) the [program] code is executed until WEND is reached, at which point control passes back to the
WHILE line.
While the end of file #1 has not been reached, read each complete line and write it to file #2.
Unlike FOR and DO, it is not possible to EXIT from a WHILE loop
Authors [edit]
< Programming:QBasic
Category: QBasic