An individual function consist of nothing more than a set of instructions for manipulating data. At bottom, it is very like a recipe.

Charlie's Asparagus

1/2 lb asparagus

2 tbs water or lemon juice

1/4 cup non-fat sour cream

1 tbs. soy sauce

5 drops Sesame oil

Directions

  1. Put asparagus spears in a microwavable dish with a tight fitting lid.
  2. Add water or lemon juice.
  3. Fit lid & microwave on high for about four minutes.
  4. Put non-fat sour-cream in a small bowl. Add other ingredients and mix well.
  5. Drizzle onto hot asparagus. Serve

The list of ingredients in Charlie's Asparagus corresponds to the data in a function

The directions are like  instructions. In particular, they proceed sequentially in steps.

Almost all cookbooks list recipes in the format you see at right-and C++ uses the same format. Data must be listed—we would say declared—before the instructions can refer to it.

So we have two aspects of a function:

  1. Its data
  2. Its instructions

Here we focus on the data

Variables are a mechanism C++ uses to store data.

They are similar to the ingredients in a recipe except that variables generally change throughout the program whereas ingredients are always the same for a recipe. Remember those old age problems, you know, George is twice as old as Samantha... Although we can write computer programs to solve such problems, they're a little beyond you just now. But writing a program to create such a problem isn't hard.

If you compare the structure of the main function above to the structure of the recipe for Charlie's Asparagus, you'll see the similarity. So, the first rule of variables is like the first rule of recipes. Instead of declaring all your ingredients before telling someone how to use them—

Variables must be declared before they can be used.

The name variable is taken from Mathematics.

We get two things from these definitions that are fundamental to variables

  1. a variable can take on any value from a set of values.
  2. a variable holds data

Type

Point 1 implies that different variables may take on values from different sets. This is the notion of type .

C++ supports all kinds of different types, in particular:

int
integer variables can hold any integer between -MAX_INT and +MAX_INT where MAX_INT is a constant which depends upon the operating system and compiler you are using. In the Teaching Machine MAXINT is 2,147,483,648
char
character variables hold any character in C++'s alphabet. Includes
  • all the upper and lower-case letters (A-Z and a-z)
  • the digits (0-9)
  • standard punction characters (.,<>?":}{} etc.)
  • some special characters ('\n' - a newline, '\t' a tab, etc.)
float
double
float stands for floating point number, the name used in computing for real numbers. double stands for double-precision floating point number. The double precision simply means that it may carry more digits of precision. Even here the range of values is finite (although it is very large). We will normally use double for real numbers because the internal floating point (real) arithmetic unit in most modern computer chips works at double (or slightly better) precision. doubles usually bigger than floats.
long
a long integer. On most computers a long is bigger (requires more storage space) than an int but has a larger range of values.

The Bin Model of Data

 

The notion that a variable holds data implies that the data has to be held somewhere. In fact, computer data (and therefore variables) are held in different kinds of computer memory.

Don't worry about the kinds. Just think of a variable as a kind of box or bin.

  1. There's one bin for every variable.
  2. The bin is sized to fit the type of data exactly.

If you imagine millions of bins stacked up, you have a pretty good idea of what computer memory looks like.

Finding the Right Bin

With millions of bins, how do we find where we put something? Well, we could

  1. put a label on the bin .
  2. remember the number of the bin we put it in.

The label we put on a bin is called its name . The number is known as its address (just like a street address which let you find the right house on a long street).

Names are for people (programmers). The computer uses the number.

Variable Attributes

If you've done any word processing at all you know there's lots of things that define a font.

There's the name of the font, for example the standard HTML fonts

Arial (sans serif)     Times New Roman (serif)    Courier New (mono)

There's the style of the font:    normal    bold    italic     bold italic

We can colour the font:     red      blue       green

Or we can change its size:     normal    bigger   even bigger    smaller

And we can do all this good stuff at once:   bigger bold red arial     smaller italic blue Times New Roman

name, style, colour and size are all attributes of a font.

Variables have attributes as well. so far we have learned about four of them:

type which determines the size of the bin and the kind and range of values it can store.

address which the computer uses to determine the location of the bin in memory.

name which gives programmers a convenient way to find/refer to the bin.

value which is the actual piece of data contained in the bin.

There are others, but these will do for now.

Declaring Variables

Repeating our rule

Variables must be declared before they can be used.

The form of a declaration is

type name = expression ;

where type will be a C++ type like int, char,or double. The name is decided by the programmer, according to the naming rules . The = expression is optional and is for giving the variable an initial value (initialization).

So,

We give each variable declaration a line of its own (although not required by the language it is good style).

Lets see some of this in action

Function Parameters

Function parameters are very similar to variables. Recall the triangleArea function

The implementation of the function consists of the function prototype

double triangleArea(double base, double height)

followed by the body of the function which contains the actual code. The prototype contains two double parameters, base and height. Effectively, they act as the first two (and in this case only two) local variables in the function.

Let's consider a slightly more difficult problem. In third year electrical engineering students may learn to calculate the gain of a standard four resistor differential amplifer as

where the Ad represents the gain and the four different R's represent the four resistor values. It's not really important where this equation comes from or what it means. Such relatively complex equations are common to all engineering disciplines. How would we write a function to compute Ad?

First of all, what would the prototype look like?

double ampGain(double rF, double rG, double r1, double r2)

Of course we can't create variable names with subscripts but we have a usable approximation in the names above. Writing the code to implement this is not terribly complicated. Just return the computer equivalent of the expression on the right side of the equation.

double ampGain(double rF, double rG, double r1, double r2){
     return (rF/r2)*(2*rG*rF + rG*r1 + rF*r2)/(rG*rF + rF*r2);
}

There is an efficiency problem, however. Multiplication of reals is quite expensive so it seems a pity to repeat them un-necessarily. Here is an alternative.

  1. What's the advantage?
  2. Do you think it matters?

Exercises

  1. Run the following example in the Teaching Machine and use it to answer the questions underneath.

  1. First step through the variable declarations. To what memory location is each variable assigned and how many bytes long is it?
  2. Which variables have been initialized and which have not?
  3. Step through the first two assignments. Can you explain why k is not equal to j?
  4. Which variables have valid values replaced by assignment?

i: at 8192, 4 bytes.   j: at 8196, 8 bytes.   k: at 8204, 4 bytes.    y: at 8208, 8 bytes.   x: at 8216, 4 bytes.    character: at 8220, 1 byte.

i,  j,  x and character have been initialized. k and y have not been initialized.

j is a long integer with a very large value of 98,765,432,199. This is bigger than the MAXINT, the largest possible int value (which is 2,147,483,648 for the Teaching Machine). If you switch to binary view you will see that k (which is an int) was created from j simply by copying the bit pattern for the first 4 bytes (or first 32 bits). The very highest bit is the sign bit. Since it was a 1, the value for k is interpreted as being negative. Converting a long to an int is always dangerous.

x is changed from 7.3 to 88.0 and y is changed from 44.0 to 1.60217646e-19