Key syntax elements for lab 4

The C++ feature we will focus on for lab 4 covers pass-by-reference, the bool datatype, loops, and random number generation. (Refer back to the course notes or to the lab 3 syntax examples for refreshers on the syntax used earlier.)


Pass-by-reference

Remember that regular parameter passing simply passes a copy of a value, whereas pass-by-reference allows the called function to access/change the original variable passed to it.

This is done by adding the & symbol before the parameter name in the formal parameter list (in the prototype and declaration of the function).

For example, in the program below the negate function switches the passed parameter between positive and negative.
#include <iostream>
using std::cout;
using std::endl;
using std::cin;

void negate(float &orig);

int main()
{
    int x = 3;
    negate(x);
    // x has now been changed to -3
    cout << x << endl;
}

void negate(float &orig)
{
   // replace the original value with the opposite
   orig = - orig;
}


The boolean datatype

Here we introduce a new datatype, bool, that can be used to hold true/false values, e.g.
bool subtitlesOn; // will set to true if user wants subtitles, false otherwise

// use the variable to remember if a particular condition evaluated to true or false
char userChoice;
cout << "Do you wish to have subtitles turned on?  Enter Y for yes or N for no: ";
cin >> userChoice;
if (userChoice == 'Y') {
   subtitlesOn = true;
} else {
   subtitlesOn = false;
}
We can test if the variable currently holds value 'true' using if (thevariablename) or we can test if it holds value false using if (!thevariablename), e.g.:
if (subtitlesOn) {
   // .... code here to turn on subtitles ...
} else {
   // .... code here to turn off subtitles ...
}
Functions can have bool as a return type, e.g.
// return true if min < x and x < max
bool isXbetween(int x, int min, int max)
{
   if (x <= min) { // too small
      return false;
   } else if (x >= max) { // too big
      return false;
   } else {
      return true; // x is in between min and max
   }
}


Loops

The other C++ syntax we will focus on covers while loops, do-while loops, and for loops.


Pseudo-random number generation

There are many different pseudo-random number generators out there, with varying properties in terms of how well they emulate true randomness. The one we'll use for now is a simple one called rand, found in the cstdlib library.

The rand function returns a random integer in the range 0..LONG_MAX, so we need to do a little manipulation if we want to generate values in a specific range:

Special note: initializing (seeding) the random number generator
Because random number generators are just computer programs, they actually have fixed behaviour. If they were run over and over, by themselves, they would always produce the same sequence of values (so from run to run it wouldn't seem very random).

To get around this, each time we start a program that uses a random number generator we initialize, or seed, the generator with a difficult-to-predict value, which the generator then uses as the basis for that run's generation sequence.

One possible seed value is the value returned by the time function from the ctime library. (Trivia: this function returns the number of seconds since the start of Jan. 1st 1970.)

Thus a simple program to generate 50 random numbers in the range 1-100 might look like:
#include <iostream>
#include <cstdlib>
#include <ctime>

int main()
{
   // seed the rng with the current time, just needs to be done once
   srand(time(NULL));

   // generate the 50 random numbers in the range 1..100
   for (int i = 0; i < 50; i++) {
       long r = 1 + (rand() % 100);
       cout << r << endl;
   }

   return 0;
}
One weakness with using time(NULL) as the seed is that the time is measured in seconds, so if you run the program twice in the same second then it will use the same seed both times, and hence the same RNG sequence both times.