HOME - - - - - - - - - Other material for programmers - - - - - - - - - Pascalite Tutorial Table of Contents

Pascalite Programming: More on Variables

This version of this tutorial is fine tuned for the open source FPC, aka Free Pascal. Most of what you read here should also directly apply if you are using Borland's Turbo Pascal (TP hereafter). It is also available for free. Please send me an email with "complaints" if something doesn't work!

If you have a Pascalite, or the software emulation, then there's a separate tutorial for you, covering much of the ground as presented here for the FPC/ TP crowd.


In the previous tutorial, we created and used our first variables. They were "string" and "integer" type variables. The string variables could hold strings of any characters (but you couldn't do arithmetic with the variables). The integer variables couldn't store letters, but they could do arithmetic with stored numbers. (Only whole numbers, and probably not below -2147483648 nor above 2147483647, but that's another story! Perhaps that range of numbers will be sufficient for now? As long as you don't need fractions.)

Variables for numbers was a good place to start, but you can store other TYPES of data, and once you know about that, the program we wrote last time can be written more simply. Simple is always good, because it makes your code more clear... helping reveal any mistakes.

While "types of data" makes sense to anyone, for programmers, especially Pascal programmers, the word type is important. If a variable has been declared to be of, for example, "type" integer, you get a set of advantages and a set of limitations. Accepting these limitations means that it is harder to write programs with bugs, and it is easier for the person who writes the compiler to do a good job. (The compiler takes your program and converts it to what the computer needs.)

The next type of data I'm going to show you is Boolean data. A Boolean variable holds either "true" or "false".


First a little history....

I first wrote this series of Pascal tutorials for the Pascalite. The version you are reading, the FPC/ TP version, is a clone from the Pascalite version.

The Pascalite, while having a more limited version of the language, is blessed with some special hardware advantages. A few of the tutorials at the start of the series depend quite heavily on those features. When you read the rest of this tutorial, you may notice where things got a bit strained as I tried to cover the same ground in a FPC/ TP environment. Sorry! Still worth what you're paying?

Although this tutorial starts weakly, it actually ends more strongly than the tutorial it derives from. Swings and roundabouts. Life.

Enter the following, or create it from the program created during the previous tutorial. It is very nearly the same code. I've changed the program name, added the lines at //**1 and //**2, and slightly changed the line at //**3. And yes, this code could be improved, and yes, the changes are trivial in effect. They do show you something new, though, which also has non-trivial uses!

program Fourth;
uses crt;

var sItWas, sLatest:string;
  iCount:integer;
  boMatch:boolean; //** 1

begin
ClrScr;
iCount:=0;
writeln('Type a short word, then press the "Enter" key.');
writeln('This will set the password to be matched later.');
readln(sItWas);
ClrScr;
repeat
  iCount:=iCount+1;
  writeln('You have gone through the loop ',iCount,' times.');
  writeln('Type the password again to leave this loop, or');
  writeln('type something else. In either case, then');
  writeln('press the "Enter" key');
  readln(sLatest);
  if sLatest=sItWas then boMatch:=true //no ; here
     else boMatch:=false; //** 2
  if sLatest=sItWas then writeln('Bye') //no ; here
     else writeln('No, that was not the password.');
  writeln;//this causes a blank line.
until (boMatch) or (iCount>5);//** 3
writeln('Press the "Enter" key to end the program.');
readln;
end.

First a simple matter: The variable names. You could call them Dick and Jane. But it is better to use names that mean something. The "bo" prefix doesn't MAKE the variables Boolean... the var statement does that... but if you use such variable name prefixes, it will help you remember what the variables are being used for. I normally prefix variables of type string with an s which is why, in the previous program, I used sItIs and sItWas as the names.

Let's look at the additions and the change....

//** 1: This creates, "declares", the boolean variable we're going to use. Always declare a variable before you use it.

//** 2: This new "if... then... else..." statement assigns a value to boMatch, depending on what is on sLatest and sItWas. If the contents of those variables match, then boMatch is true after this statement has executed. See how sensible variable names make your code easy to follow? Choose your variable names accordingly.

In a previous tutorial, we said that it is important to initialize variables. You may have wondered why there wasn't a "boMatch:=true;" (or maybe ":=false") before the repeat loop. Look at the code. boMatch will always have something put into it during line //**2's execution. And we never try to consult what is in boMatch until line //** has executed at least once. boMatch is initialized the first time we pass through //**2, and that is soon enough.

//** 3: In this line, we've replaced the condition "sLatest=sItWas" with "boMatch". It is, as you may realize, a very trivial replacement. But is all this clear to novices in my readership? When the program comes across "sLatest=sItWas", the computer goes off and "looks" at what's in sLatest, and what's in sItWas, and compares them, in the place of condition, one is left with the equivalent of a "true" or of a "false". A programming text might (quite properly) say that "sLatest=sItWas" returns a Boolean value, with something drawn from the list of possible values for a Boolean type datum, i.e. "true" or "false".

The idea of "boiling things down", of something "returning" something is important. It lets you look at a program at different levels. Sometimes you need to concentrate on detail; sometimes on the broader picture. In the program above, sometimes you need to look at the detail of what makes boMatch true or false. You do that by looking in the if... then... else... statement. At other times, you're more worried about what happens when there was a match, as in the line "until (boMatch) or..."

The relatively trivial move of the test of "if sLatest=sItWas", and the storing of the result in boMatch, is one of those things that arose from making this tutorial derive nicely from the older Pascalite tutorial. But the code is perfectly valid, perfectly correct... and not unlike something that you might encounter in other, less trivial, circumstances. We'll come back to this later.




That takes care of a lot of things. Now to address a few loose ends. In general, it is best to read these tutorials with your browser not filling your screen, and adjusted to make a comfortably narrow column of text. You may need to widen it a bit to see all of every line of the code which is coming up.

Surely you thought that....

if sLatest=sItWas then boMatch:=true //no ; here
    else boMatch:=false;
if sLatest=sItWas then writeln('Bye') //no ; here
    else writeln('No, that was not the password.');

was dreadfully messy? You were right! And Pascal code doesn't need to be, and shouldn't be, messy. In an earlier tutorial, we talked a little about nested "begin... end" blocks.

An "if... then ... else... " statement, as used to date, needs "things" plugged in where I've put "...". The first "thing", as you know, must be a condition, something that returns, boils down to, "true" or "false".

After the "then" and after the "else" we have, to date, put simple statements, e.g. "boMatch:=true"

If you "wrap" several simple statements up in a "begin... end" block, they become, effectively, "one" statement. They "boil down to" "one" statement. (That "boil down to idea again!)

When you "wrap" statements together thus, you put a semicolon between each. I think of it as "glue". This is just a continuation of the general use of the semicolon at other levels of the program's editing. Note: "if... then... else" is ONE, SIMPLE statement. That's why there are no semicolons in it, say just before the else, which is a tempting place to put one.

The following is equivalent to what we had before, and a form you will come to see as neater. I would guess it looks neater to you even now when it is unfamiliar?

if sLatest=sItWas
     then begin
            boMatch:=true;
            writeln('Bye');//**1
            end;//no ; here //**2
     else begin
            boMatch:=false;
            writeln('No, that was not the password.');//**3
            end;//else **4

(I've exaggerated the indenting, to make my point.)

We still have "if... then... else...". Look at the code carefully; be sure that you see that.

The "//no ; here" that I've put on line //**2 is something that I routinely put in my code. If in doubt, put semicolons in... they often do no harm, but a semicolon before an else is always bad news.

Strictly speaking, you don't need the semicolons at //**2 and //**3, but I would put them in.

You don't need them, because they would be to "glue" another simple statement into the compound statement between the "begin" and "end". The word "end" tells the compiler that the "begin... end" block ends here. A semicolon after the last statement before the "end" simply "glues" a "do nothing" statement onto the compound statement between the "begin" and "end".

I would put those semicolons in, because it is quite common to go back and add other things to the compound statement, and if you didn't put the semicolon in when you wrote what was there before, you may well fail to do so when you add the new line.

Moving on with "begin... end": Be very careful that every "begin" is matched by an "end".

Once you start using the "begin... end" "trick" to make a number of simple statements behave as one statement (it's called a compound statement), be careful to remember the "begin" and "end" around the simple statements. It is quite easy to write the following when you meant the code most recently presented....

if sLatest=sItWas
     then begin
            boMatch:=true;
            writeln('Bye');
            end;//no ; here
     else
            boMatch:=false;
            writeln('No, that was not the password.');

The "then" part is unchanged, but look at what is supposed to happen in the "else" situation.

Set out like that, the error is fairly easy to see... another reason for setting things out like that... but I assure you: You will sometime spend a few hours tracking down a mistake like that. Like what? I'm going to explain...

With the faulty code, instead of the "writeln('No, that was not the password.');" happening only when sLatest does not equal sItWas, it will happen every time. It has become the first statement after the "if... then... else..." The "..." part for the "else" is now simply "boMatch:=false;"

Trust me: Be careful with your "begin... end" pairs.

Moving on again: One way to help yourself avoid errors is, when entering code, to type both the "begin" and the "end", and then go back and fill in what they are "gluing" into a single compound statement.

I.e., I would have entered the code you see above in the following steps....

if sLatest=sItWas
     then begin
            end;//no ; here
     else begin
            end;//else

... followed by....

if sLatest=sItWas
     then begin
            boMatch:=true;
            writeln('Bye');
            end;//no ; here
     else begin
            end;//else

... and then I would have entered the stuff between the "else"s "begin... end".

Take a deep breath. Make sure you're clear on the above. I'm about to go on to a related topic.

Ready? Okay....

You've already seen something rather like the "begin... end" block. I'll leave a big vertical blank space so you can think "What could that be?" before seeing the answer.







... answer further down page...







... answer further down page...







Answer: The "repeat... until" block is like the "begin.. end" block, in that it can "glues" a bunch of stuff together into a "single" "thing".

The "repeat... until" block is slightly "fancier" that the "begin... end" block. (You may go through the block more than once, which you won't do with a "begin... end" unless there is something outside of it causing the repetition.) However, just like "begin... end", the words "repeat... until" will have one or more statements between them. (A "begin... end" block with only one simple statement in it would be pointless.... but it would work.) If there is more than one simple statement in the block, there should be a semicolon between each of them. Thus, strictly speaking, one could say that either type of block has "one statement" in it... either a simple statement, or a compound statement (simple statements "glued" together with semicolons). That bit of cleverness is not mere academic pedantry. You should try to see your program's structure in these terms.

=====

And now for something completely different!

In the program we've been discussing, the boMatch variable is pretty superfluous. It could be written out with no loss of clarity.

However, what we did does sometimes have its uses, particularly in more complex programs.

Imagine a program not unlike our example program. A sketch of the important bits is as follows. N.B. What follows is not complete code, it would never run....

repeat
   boMatch:=false;
   if (first complicated possibility) then boMatch:true;
   if (second complicated possibility) then boMatch:true;
   if (third complicated possibility) then boMatch:true;
   if (fourth complicated possibility) then boMatch:true;
until boMatch;

... and that's the simplified code! You will get loops (and other structures) with all sorts of things going on within them, with all sorts of ways for the time to leave the loop to arise. What we've done above is useful: Set "boMatch" false, to begin with, knowing that it can always be made true anywhere below the initialization, and thus trigger an exit from the loop, if the time has come, however arcane the indication thereof, to do so.

=====

Moving on again...

This is a "scrap" that doesn't fit the FPC/ TP tutorial very well, but it was covering in the Pascalite tutorials at this point, so I'm shoehorning it in here, so you'll be ready for subsequent things.

Forget the program we've been discussing. Consider a program about the weather with three boolean variables: boCold, boRaining, and boSnowing.

Starting with the very, very easy:

if boCold then writeln('Put a coat on.');

Easy? Yes. But note two things: You don't have to say "if boCold=true...". If boCold is holding "true", then "boCold=true" boils down to "true", so it would work. But "boCold" on it's own, when the variable boCold holds "true" also boils down to true, and more quickly, so there's no need for the longwinded version.

In different circumstances, you might want to say "if boCold=false..." which is perfectly acceptable. Alternatively, you can say "if not boCold".

"Not" is a reserved word... it is part of the Pascal language, like "begin", "end", etc. It is a boolean operator. Consider, for comparison, mathematical operators. There's "squared" for instance. 3 squared is 9. "x squared" boils down to the number multiplied by itself. A boolean thing "not"ed boils down to true if the boolean thing was false, and to false if the boolean thing was true.

This is usually depicted with a truth table:

"Boolean thing"   NOT "Boolean thing"
    false             true
    true              false
The equivalent for "squared" would be....
"Number"   "Number" squared"
   1           1
   2           4
   3           9
   4          16
   ... etc

Pascal would also be quite happy with the following...

if boRaining or boSnowing then writeln('Bring umbrella.');

"Or" is another Pascal reserved word, as is "and". They are two more boolean operators. Where "not" operated on a single boolean value, "or" and "and" operate on two values, returning ("boiling down") to a single value. Because there are two "inputs", these operators are called binary operators. (The name has nothing to do with the fact that they are sometimes applied to numbers you may be thinking of in binary form.) Can you think of some binary operators used in everyday mathematics?







... answer further down page...







Answer to "Name some binary operators used in everyday mathematics": Easy! Adding, subtracting, multiplying, etc!

Here are the truth tables:

(BT= "Boolean Thing")
  "BT1"    "BT2"   BT1 AND BT2
 false     false     false
 false     true      false
 true      false     false
 true      true      true

  "BT1"    "BT2"   BT1 OR BT2
 false     false     false
 false     true      true
 true      false     true
 true      true      true

The equivalent for "added" would be....

"Num" for "number"
"1stNum"   "2ndNum" 1stNum PLUS 2ndNum
   0           0           0
   0           1           1
   0           2           2
... snip...
   9           7          16
   9           8          17
   9           9          18
   ... etc

So far, we've looked at simple conditions. You can get "clever"....

if (boRaining or boSnowing) and boCold then writeln('Bring umbrella and wear coat.');

Note the use of the brackets, (), to indicate the order of operations. Because of the brackets, you first boil down the "boRaining or boSnowing" to a "true" or a "false". You then "and" that with what's held in boCold to get the final "answer" to whether you do the "then" part or not.

N.B. You will often write conditions like "iCount>5". (We had that as part of our program. Revisit the text farther up the page, if you are unclear about this.) If you have one of those in a compound condition, put it in brackets. Also put anything with an equals sign in it in brackets, e.g.

if (iCount=5) and (boRaining=false) then...

Without the brackets, Pascal sometimes does unexpected things, like trying to treat the foregoing as....

if iCount=(5 and boRaining)...
.. which will cause a compiler error. Because of the brackets which are effectively there, the compiler starts by trying to "and" 5 with the value in boRaining. How do you "and" a number with "true"/ "false"? (Although you are able to treat booleans as numbers sometimes... just often enough to fool you, if you get sloppy. And you can AND or OR numbers with numbers... but that, alas, is a story for another day. Was your sigh disappointment? Relief?)

Just before we end, I'm going to give you one more Boolean operator, just to round out the story....

The Boolean operator "xor" was named from the words "exclusive or". It is a special case of the "or" operator. Truth table....

(BT= "Boolean Thing")
  "BT1"    "BT2"   BT1 XOR BT2
 false     false     false
 false     true      true
 true      false     true
 true      true      FALSE

When you use the ordinary "or" to combine two boolean things, the result, the boiled down single Boolean answer is "true" if the first OR the second of the things you were ORing together were true. This includes the case where both of the inputs are true. The EXCLUSIVE "OR" excludes this case. boCold xor boRaining only boils down to "true" if boCold is true, OR if boRaining is true, but the result is FALSE (not true) if BOTH of them are true.

So! Now you know a lot more than you did! There are more tutorials for you as soon as you recover from this session.


Summary....

(Sorry... I'll try to write one someday!)




Please also note that I have two other sites, and that the following search will not include them. They have their own search buttons.

My Sheepdog Guides site.
My Arunet site.

Go to the sites above, and use their search buttons if you want to search them.
To search this site....

Search this site or the web powered by FreeFind

Site search Web search
The search engine merely looks for the words you type, so....
*    Spell them properly.
*    Don't bother with "How do I get rich?" That will merely return pages with "how", "do", "I"....

You can also search this site without using forms.
Ad from page's editor: Yes.. I do enjoy compiling these things for you... hope they are helpful. However.. this doesn't pay my bills!!! If you find this stuff useful, (and you run an MS-DOS or Windows PC) please visit my freeware and shareware page, download something, and circulate it for me? Links on your page to this page would also be appreciated!
Click here to visit editor's freeware, shareware page.


Want a site hosted, or email? You can also help me if you sign up via this link to 1&1's services. (I wouldn't recommend them unless I was happy after several years as one of their customers, but yes, they do pay me if you use this link! As do the Google advertisers, about whom I know nothing, of course.)



Valid HTML 4.01 Transitional Page tested for compliance with INDUSTRY (not MS-only) standards, using the free, publicly accessible validator at validator.w3.org


Why does this page cause a script to run? Because of the Google panels, and the code for the search button. Also, I have some of my pages' traffic monitored for me by eXTReMe tracker. They offer a free tracker. If you want to try one, check out their site. Why do I mention the script? Be sure you know all you need to about spyware.
Editor's Main Homepage
How to email or write this page's editor, Tom Boyd

....... P a g e . . . E n d s .....