When programs get big, you need to break them into
smaller pieces that are easier to work with. QBASIC calls
these pieces "sub-procedures" or SUBs. Other programming languages
have other names, like procedures, subroutines, or subprograms.
To work with SUBs in QBASIC, we need to look at
the "SUBs" dialog box which shows us a list of our SUBs.
Select "View | SUBs..." from the menu to bring up the SUBs dialog
box. You can also press the F2 key to get there more quickly.
In here, you can select a SUB to work with, or
you can select the main module. If you are just starting with
a clean slate (File | New) you'll see that the main module is
called "Untitled", and there are no SUBs.
You can define a new SUB in QBASIC simply by typing
it in. This will jump you to the view of the new SUB.
Try typing this:
SUB DrawCircle CIRCLE (320, 240), 100, 15 END SUB
Notice that after you pressed enter on the first line, you
were taken to a new screen with just your new SUB in
it. Now, if you go to the SUBs dialog box (View | SUBs...), you
can see that you have a SUB named "DrawCircle" and a
Main Module named "Untitled".
Now we need to go back to the Main Module ("Untitled") to
actually use the new SUB. From the menu, select
View | SUBs... to get the SUBs dialog box. Now double-click
on "Untitled" to get back to the Main Module. The screen will
go blank, but don't worry, your SUB is still out there.
Now type this in and run it:
SCREEN 12 CLS DrawCircle
See? DrawCircle did what it was supposed to do.
Let's try adding another SUB. See if you can
remember the steps on your own. Refer back to the previous
example if you need help.
SUB PlayMary PLAY "e8 d8 c8 d8 e8 e8 e4" END SUB
Now we need to change the Main Module to use our new
SUB. So, go back to the Main Module, and change
it to look like this:
SCREEN 12 CLS DrawCircle PlayMary
Now run it and you should see the circle and hear the song.
Dividing programs into smaller pieces like this will help you
make sense out of big programs.
Arguments
Sometimes you want to pass numbers or strings to a SUB.
QBASIC lets you do this. Here is a new version of the DrawCircle
SUB:
SUB DrawCircle2 (Radius) CIRCLE (320, 240), Radius, 15 END SUB
This version lets us pass in the Radius. When we do this, Radius
is called a "parameter" or "argument" to our SUB. Here's
how we would then pass an argument from the Main Module:
SCREEN 12 CLS DrawCircle DrawCircle2 (20) PlayMary
We could also do something like this in our Main Module:
SCREEN 12 CLS FOR I = 5 TO 200 STEP 5 DrawCircle2 (I) NEXT I
Changing Arguments
If you need to tell the main module something, you can change
one of the arguments in your SUB, and the main module will see the
change.
CLS I = 0 AddOne(I) PRINT I
SUB AddOne(X) X = X + 1 END SUB
When you run that program, it will print the value 1 on the
screen. This is because the value of I is changed by the AddOne SUB.
If you only need to return one value, a FUNCTION is sometimes a
better choice. FUNCTIONs are described later.
Scope
What if we had variables in the Main Module and in a SUB
that happen to have the same name. Would they be the same variable?
Let's find out. Enter this SUB:
SUB Scope PRINT "Scope says: "; X X = 23 END SUB
And this Main Module:
X = 15 Scope PRINT "Main Module says: "; X
And run it. What happened? Scope said "0" because to Scope, X
was a new variable. Main Module said 15, because Scope didn't change
Main Module's X, it changed it's own X. Scope's X and Main Module's
X are different variables.
Variables that you create in a SUB cannot be seen by the
Main Module. Variables in the Main Module cannot be seen by a
SUB. If you need to share variables, you can pass them
as arguments to the SUB.
Global Data
It is possible to make variables in the Main Module available to
SUBs without passing them as arguments. Add a "SHARED X" to the
Scope SUB like this:
SUB Scope SHARED X PRINT "Scope says: "; X X = 23 END SUB
Now when you run it, you'll see that the Scope SUB can now see the Main
Module's X. Scope no longer has its own X. This is called "Global
Data" (since it can be seen by everyone) and should be avoided
if you can. Most programmers consider this dangerous since it
is hard to know which SUB might change a global variable.
You can also make a variable global to all SUBs from the Main
Module by adding a "DIM SHARED" to the main module before you set X
to 15:
DIM SHARED X X = 15 Scope PRINT "Main Module says: "; X
This makes it easier to see which variables are global since
they can be found in the Main Module. The problem is that this
makes a variable global to every SUB in your program. Usually,
only some SUBs need to see a global variable. It is better to
use SHARED within your SUB in that case.
Object Oriented Programming
When you start worrying about SUBs and the Main Module
sharing variables, you are probably ready to begin learning Object
Oriented programming. Object Oriented programming makes it easier
to share variables between SUBs and still write code that
is easy to understand. Visual BASIC, Java, and C# are programming
languages that provide Object Oriented programming features, and
are fairly easy to learn.
STATIC
Notice that each time you call a SUB, its variables
are lost after the SUB is over. Here's an example:
SUB Counter C = C + 1 PRINT C END SUB
CLS Counter Counter Counter
Not a very good counter, since it always prints "1". We can
use STATIC to tell QBASIC that we don't want C to go away after
the SUB is over. Then we will get the behavior we
expect. Change the Counter SUB like this:
SUB Counter STATIC C C = C + 1 PRINT C END SUB
That's much better.
Object Oriented programming languages offer many ways to avoid
the use of STATIC variables. If you find yourself making lots of
STATIC variables, it is probably time to learn an Object Oriented
programming language.
Functions
Functions are just like SUBs, but they return a value.
Here's an example:
FUNCTION Add (X, Y) Add = X + Y END FUNCTION
And here's a Main Module to go with it:
PRINT Add(3, 4)
Well, I DECLARE!
As you've been entering the example programs in this chapter,
you may have noticed that the QBASIC editor adds "DECLARE" statements
to the programs. Why does it do this? The DECLARE statement is
a warning to QBASIC to let it know that there are SUBs or
FUNCTIONs in this program. Without this warning, QBASIC would have
no idea what we mean when we call a SUB or FUNCTION. It would think
it had found a syntax error and the program would stop.
Fortunately, QBASIC handles making DECLAREs for us.
Unfortunately, in larger programs, it might put the DECLAREs
someplace that looks ugly. Fortunately, you can move the DECLAREs
anywhere you want (as long as it is before the FUNCTION or SUB is
first used) and QBASIC still takes care of the rest.
Source: http://jpsor.ucoz.com |