I certainly fall into the lower-skilled group...these few posts on
strings, stacks,passing variables etc have got me totally lost, although I do understand the
need to follow larger programs, I have one using a GLCD that is currently at 3800 bytes (no
attempt at optimising yet) and I struggle to follow it, even though iI wrote it!!
If you can manage a 3800 byte program, you're definitely not a member of the lower-skilled group!
In the posts above, forget about all the jargon. What we're all getting at is a better way to
write and maintain Picaxe BASIC code.
Right now, you know that all memory is global. That is, every memory register can be read
and written by any line of the program, located anywhere. This causes huge problems in a
large program.
Let's say you're using b6 for something in one subroutine. b6 can be read and written by
any line, in any subroutine or your mainline, anywhere in your program. With your large
program, I'm sure you've encountered problems remembering just what you're doing with
each memory register in all you're program's code. It's only too easy to write code that
modifies the value of b6 that you're using somewhere else. If you didn't mean to overwrite
b6's value, maybe because you wrote the code that used the original b6 last week and you
forgot that you did, you'll have a serious bug in your code.
This is a particular problem if you've named b6 something else. Just reading the name
won't give you a clue that it's a global memory register, other than the fact that, right
now,
everything is a global variable.
To get around that problem, we want local variables. This just means that any subroutine
can have memory that's available only to that subroutine, memory that can't be written or
read outside that subroutine.
Let's look at one possible example of a subroutine that uses local variables:
Code:
Add:
; Declare two local variables, var1 and var2, of data type byte. These will exist only within
; this subroutine.
; They are created when the subroutine is first called, and disappear when the subroutine
; returns.
; They can't be accessed by any code outside this subroutine.
; You can even name other local variables var1 and var2. Matter of fact, you could
; have many locals named var1 and var2. With the local variable mechanism, none of
; these var1 and var2 thingies can interfere with one another.
; If locals are implemented well, these variables will be initialized to zero, automatically,
; when they are created
byte var1
byte var2
; Do something with these locals
var1 = 14
var2 = 23
var1 = var1 + var2
; Put the result in a global variable that can be accessed outside of the subroutine
b6 = var1
; Return from the subroutine. var1 and var2 are automatically destroyed at return
return
Parameter passing is a way to feed the subroutine with input values without using global
memory registers, which again prevents overwriting a memory register inadvertently.
Code:
; The subroutine call: the two parameters passed can be any value or existing variable,
; either local or global. The subroutine will take these two values as its input.
gosub Add(14,23)
; or
number1 = 14 ; number1 and number2 can be either local or global variables
number2 = 23
gosub Add(number1,number2)
; The subroutine label now contains a parameter list that tells you the subroutine expects
; to receive two values from the calling statement. If the calling statement doesn't match
; the paramter list format declared here, the compiler generates an error message.
Add(val1,val2):
; do something with the passed-in parameters:
b6 = val1 + val2
return
; Note that the only global memory register used in this whole call and return operation
; is b6. None of the other variables can be accessed by any other code in the program.
; Note also that the variable names used in these operations are unique to the lines
; where they are used, not global within the program. You could use the names var1 and
; var2 anywhere else in the program without interference with this particular operation,
; and without generating a compile-time error. You don't have to remember whether
; or not you've used a variable name elsewhere in your program.
Now let's take care of that nasty ol' global variable that we're using to return the
subroutine's result. Doing so will remove any possibility of inadvertent interference with our
operation by any code located elsewhere in the program. Let's first start with the
subroutine:
Code:
Add(var1,var2):
var1 = var1 + var2
return var1 ; This tells the subroutine to return the value of var1 to the calling statement
The calling statement might look something like this:
sum = gosub Add(number1,number2)
The subroutine will add the values of variables named number1 and number2, then return
the result to the calling statement. The calling statement will then take the result and
store it in a variable named sum. sum can be either a local or global variable.
Note also that the names used in the parameter list of the calling statement don't have
to match the names used by the subroutine's parameter list.
So, from these examples, I think you can see that local variables and parameter passing
makes your life as a programmer much easier.
You don't have to have a photographic memory in order to write code that's results can't be
inadvertently modified by code eslewhere in your program, code that you wrote, perhaps, a
week or a year ago.
You don't have to worry about unique variable names.
The code is much easier to read, too. And modification is also much simpler and very much
safer. With variable values and names isolated throughout your program, you don't have to
worry about a tiny change to your program inadvertently screwing up something, totally
unrelated, elsewhere in your code.
Way back when, a friend of mine coined a term for HP BASIC which, at that time, shared
the same problems as Picaxe BASIC: no local variables, no local variable names, no
parameter passing, and no return values from subroutines. He called that "holographic
code." A tiny change made at one place in the program would affect every other thing in
said program.
Did I clear it up for you, or did I confuse you further?
Have fun!
Tom