Variables, Values, and Types

A variable is a group of memory cells that holds a value. The value stored in variable, hence the variable itself, can be classified according to its type:

Built-in types
   Arithmentic Types
      floating point types
         float (single precision)
         double (double precision)
         long double (extended precision)
      Integral Types
         bool
         character types
            char
            unsigned char
            signed char
            wchar_t
         integer types
            int (short, long, or regular)
            signed (short, long, or regular)
            unsigned (short, long, or regular)
   array types
   pointer types
   reference types
   void (type unknown)
User-defined types
   enumeration types
   classes (includes structs and unions)

The type of a value determines how the value is represented inside the computer and what operations can be performed on the value.

In addition to these types, the C++ standard library supplies some standard classes:

string
istream
ifstream
istringstream
ostream
ofstream
ostringstream
vector<...>
list<...>
map<...>
stack<...>
queue<...>

The last five are called templates. For example:

list<int> = type of all integer lists
list<string> = type of all string lists
list<vector<char> > = type of all lists of vectors of characters

If a programmer doesn't like the name of a type, he can always introduce an alternative name using the typedef declaration:

typedef float TEMPERATURE;
typedef string TEXT;
typedef vector<double> POINT;

Statements

Internally, a C++ program is always a function called main(), which consists of a sequence of statements and returns an integer exit code to the operating system when it terminates. Conventionally, exit code 0 indicates successful completion:

int main()
{

   STATEMENT
   STATEMENT
   // etc.
   STATEMENT
   return 0;
}

Note that the sequence of statements is indented and surrounded by curly braces. The sequence may also include comments:

// this is a one-line comment

 

/*
this is a multi-
line comment
*/

Compilers ignore comments, indents, spaces, and blank lines; they are intended only for human readers.

There are three types of C++ statements: expressions, declarations, and control structures:

STATEMENT ::= EXPRESSION | DECLARATION | CONTROL

Executing an expression produces a value. For example, the expression:

6 * 7;

produces the value 42. Expressions can also update variables and perform I/O. Note that expressions and declarations are terminated by semicolons. Executing a declaration introduces a new name. When the program runs, each statement is executed in order unless one of the statements explicitly changes the order. Control statements alter the execution sequence. This is useful if one statement needs to be repeated many times or if a statement should only be executed if a particular condition is true. For example:

return 0;

in main() terminates the program and returns the exit code 0 to the operating system. Any statements that follow it are ignored:

int main()
{
   STATEMENT
   STATEMENT
   // etc.
   STATEMENT
   return 0;
   STATEMENT // ignored
   STATEMENT // ignored
}

Declarations

A declaration creates and names a variable. For example:

int x = 23;

creates an integer variable called x initially containing 23. We can represent the situation graphically as:

The box represents the variable, the arrow connecting the name x with the variable represents the address of the variable. More on addresses, later.

We can use x as a synonym for the value it holds. For example, the expression:

x + 10;

produces the value 33 when it is executed.

A declaration can create several variables simultaneously. For example, the declaration:

string prompt = "Enter data", msg = "Thank you";

creates two string variables called prompt and msg initialized to "Enter data" and "Thank you", respectively.

A constant declaration creates a read-only variable. For example:

const double pi = 3.1416;

Assignments

We can change the value stored in a variable using an assignment statement. For example, the assignment:

x = 100;

changes the value stored in x from 23 to 100. (The value produced by x + 10 wasn't written back to x.)

The assignment:

x = x + 1;

changes the value from 100 to 101.

An assignment statement is a type of expression. For example, the value produced by

x = 100;

is 100. Some programmers use this fact to assign the same value to several variables simultaneously:

y = x = 100; // assigns 100 to x and y

C++ has many exotic assignment operators. For example:

x += 5;

is the same as:

x = x + 5;

The assignment:

x = "200";

is illegal because x was declared as an integer variable, but the right side of the assignment is a string.

Function Calls

The standard C++ library contains many useful functions. To call a function, write the name of the function followed by a list of argument expressions bracketed by parenthesis:

fun(arg1, arg2, arg3);

C++ regards (...) as a function call operator. Consult the documentation that came with your compiler to find out what functions are available. here are a few examples:

acos(-1);          produces 3.14159
exp(1);          produces 2.71828
sin(acos(-1)/2);    produces 1
log10(100000);    produces 5
pow(2, 3);       produces 8
pow(49, .5);       produces 7
sqrt(49);          produces 7

Streams

An output stream is a value of type ostream. It is a sequence of characters being sent to a file, monitor, or other output device. C++ has several predefined output streams including cout and cerr:

ostream cout, cerr;

Both of these output streams are initially associated with the monitor, however cout can be redirected from the command prompt, while cerr can't. This makes cerr a perfect place to send error messages.

We can insert characters into an output stream using the insert operator (i.e. the left shift operator):

cout << "Hello everybody\n";
cerr << "Error: input must be positive\n";

This prints the strings on the monitor.

The insert operator also translates binary values into strings. For example:

cout << 42; // translates int to string, then inserts
cout << 3.1416; // translates double to string, then inserts

Because of overloading, this doesn't cause confusion. The C++ compiler can tell by the left operand, cout, that translation, not left shift is to be performed. The right operand tells it what type of translation is to be performed: int to string, double to string, etc.

Insert produces its left operand as a value, thus several output operations can be chained together on a single line:

cout << "result = " << 6 * 7 << '\n'; // prints "result = 42"

Because left shift is left-to-right associative, this is the same as:

(((cout << "result = ") << 6 * 7) << '\n');

Which is the same as:

cout << "result = ";
cout << 6 * 7;
cout << '\n';

An input stream is a value of type istream. It represents a sequence of characters arriving from a file or input device. C++ also has a predefined input stream stored in a variable called cin:

istream cin;

Characters can be extracted from an input stream and translated into a binary value using the extraction operator (i.e., right shift). For example:

double x;
cin >> x;

extracts characters up to the first white space character (tab, blank, or newline), translates these characters into the binary representation of a double, then assigns this double to x.

As with the insertion operator, several extraction operations can be chained on the same line.

double x, z;
int y;
cin >> x >> y >> z;

Right shift is right-to-left associative, so this is the same as:

(((cint >> x) >> y) >> z);

We can read strings and characters using the right shift operator:

string s1, s2;
char c;
cin >> s1 >> s2 >> c;

Example: Computing Future Value

We are now ready to write our first program. The future value of an investment of p dollars compounded monthly for n years at an annual interest rate of r percent is given by the formula:

v = p(1 + r/1200)12n

Our program prompts the user for p, n, and r, then computes and prints v.

Unfortunately, exponentiation is not built into the C++ language, but it is part of the standard library:

double pow(double x, int n); // = xn

Here is the equivalent C++ expression:

v = p * pow(1 + r/1200, n * 12);

Including Standard Header Files

Although the linker will automatically find and extract the definitions of pow, cout, cin, ostream, and istream from the standard library, the compiler will complain if we don't at least declare the types of these names. Fortunately, all type declarations of C++ library definitions are contained in 50 or so header files. For example, istream and ostream are declared in iostream.h, while the declaration of pow is in math.h. Use your online documentation to locate library functions and classes you want to use. The documentation should tell you which header files you need to include. Only use the standard library in the assignments that follow.

Create a text file called fval.cpp (or any other name). At the top of the file place these include directives:

#include <iostream>
#include <cmath>
using namespace std;

The pre-processor will replace these lines by the contents of iostream.h and math.h. The angle brackets tell the compiler to look in the "usual place" for the files. All names in these files are contained inside a namespace called std. The last line:

using namespace std;

moves these names into the global namespace. More on this later. Actually, math.h is an old C header file. All C header files have C++ counterparts that begin with the letter c, thus, cmath.h instead of math.h.

According to the ANSI standard it doesn't matter if we write the ".h" extension or not. It does make a difference in Visual C++, however. The names in iostream.h belong to the global namespace, so the "using namespace std;" line isn't needed. But Visual C++ has two stream libraries, the old and the new. Using the ".h" extension:

#include <iostream.h>
#include <math.h>

tells the compiler and linker to use the old library instead of the new.

main()

After the include directives comes our definition of main():

int main()
{
   double p, r, v;
   int n;

   cout << "Enter investment amount: ";
   cin >> p;
   cout << "Enter term of investment in years: ";
   cin >> n;
   cout << "Enter anual rate: ";
   cin >> r;

   v = p * pow(1 + r/1200, n * 12);
   cout << "Future value = $" << v << '\n';

   return 0;
}

Compiling fval.cpp produces an object file fval.obj. The linker adds the definitions from the standard library to produce fval.exe:

Our program is a DOS console application (as opposed to a Windows application). It must be run from the DOS console. Here's the output from a sample run:

Enter investment amount: 10000

Enter term of investment in years: 2

Enter anual rate: 9

Future value = $11964.1

Problem

Write a program that computes the monthly payment on a loan of p dollars amortized over n months at a monthly interest rate of r. The formula is:

m = (p * r)/(1 – 1/(1 + r)n)

Here's a sample output:

Enter loan amount: 10000
Enter term of loan in years: 2
Enter anual rate: 9
Monthly payment = $456.847