C++ Notes1
C++ Notes1
Introducing C++
Programming is a core activity in the process of performing tasks or solving problems with the aid of a computer.
An idealized picture is:
But, unfortunately things are not (yet) that simple. In particular, the "specification" cannot be given to the computer
using natural language. Moreover, it cannot (yet) just be a description of the problem or task, but has to contain
information about how the problem is to be solved or the task is to be executed. Hence we need programming
languages.
There are many different programming languages, and many ways to classify them. For example, "high-level"
programming languages are languages whose syntax is relatively close to natural language, whereas the syntax of
"low-level" languages includes many technical references to the nuts and bolts (0's and 1's, etc.) of the computer.
"Declarative" languages (as opposed to "imperative" or "procedural" languages) enable the programmer to minimize
his or her account of how the computer is to solve a problem or produce a particular output. "Object-oriented
languages" reflect a particular way of thinking about problems and tasks in terms of identifying and describing the
behaviour of the relevant "objects".
C++ includes facilities for object-oriented programming, as well as for more conventional procedural programming.
For example, it is sometimes claimed that (well written) object-oriented programs reflect the way in which humans
think about solving problems.
C++ was developed by Bjarne Stroustrup of AT&T Bell Laboratories in the early 1980's, and is based on the C
language. The name is a "++" is a syntactic construct used in C (to increment a variable), and C++ is intended as an
incremental improvement of C. Most of C is a subset of C++, so that most C programs can be compiled (i.e.
converted into a series of low-level instructions that the computer can execute directly) using a C++ compiler.
C is in many ways hard to categories. Compared to assembly language it is high-level, but its nevertheless includes
many low-level facilities to directly manipulate the computer's memory. It is therefore an excellent language for
writing efficient "systems" programs. But for other types of programs, C code can be hard to understand, and C
programs can therefore be particularly prone to certain types of error. The extra Object-Oriented facilities in C++ are
partly included to overcome these shortcomings.
/* Comments can also be written starting with a slash followed by a star, and
ending with a star followed by a slash. As you can see, comments written in
this way can span more than one line. */
#include <iostream.h>
int main()
{
int year_now, age_now, another_year, another_age;
cout << "Enter the year for which you wish to know your
age.\n";
cin >> another_year;
return 0;
}
#include <iostream.h>
This statement is called an include directive. It tells the compiler and the
linker that the program will need to be linked to a library of routines that
handle input from the keyboard and output to the screen. The header file
"iostream.h" contains basic information about this library. After the include
directive, the basic structure of the program is:
int main()
{
First statement;
...
...
Last statement;
return 0;
}
All C++ programs have this basic "top-level" structure. Notice that each
statement in the body of the program ends with a semicolon. In a well-
designed large program, many of these statements will include references or
calls to sub-programs, listed after the main program or in a separate file.
These sub-programs have roughly the same outline structure, as the program
here, but there is always exactly one such structure called main. When at the
end of the main program, the line
return 0;
means "return the value 0 to the computer's operating system to signal that
the program has completed successfully". More generally, return statements
signal that the particular sub-program has finished, and return a value,
along with the flow of control, to the program level above.
Our example program uses four variables:
Program variables are not like variables in mathematics. They are more like
symbolic names for "pockets of computer memory" which can be used to store
different values at different times during the program execution. These
variables are first introduced in our program in the variable declaration
which signals to the compiler that it should set aside enough memory to store
four variables of type "int" (integer) during the rest of the program
execution. Hence variables should always be declared before being used in a
program.
After we have compiled the program above, we can run it. The result will be
something like
The first, third, fifth and seventh lines above are produced on the screen by
the program. In general, the program statement
cout << Expression1 << Expression2 << ... << ExpressionN;
will produce an identical output. If spaces or new lines are needed between
the output expressions, these have to be included explicitly, with a " " or a
"\n" respectively.
The numbers in bold in the example screen output above have been typed in by
the user. In this particular program the statement
has resulted in the variable year_now being assigned the value 1996 at the
point when the user pressed RETURN after typing in "1999". Programs can also
include assignment statements, a simple example of which is the statement
Hence the symbol = means "is assigned the value of". ("Equals" is represented
in C++ as ==.)
The last few lines of our example program (other than "return 0") are:
if (another_age >= 0) {
cout << "Your age in " << another_year << ": ";
cout << another_age << "\n";
}
else {
cout << "You weren't even born in ";
cout << another_year << "!\n";
}
The "if ... else ..." branching mechanism is a familiar construct in many
procedural programming languages. In C++, it is simply called an if
statement, and the general syntax is
if (condition)
{
Statement1;
...
...
StatementN;
}
else
{
StatementN+1;
...
...
StatementN+M;
}
This program fragment has quite a complicated logical structure, but we can
confirm that it is legal in C++ by referring to the syntax diagram for "if
statements". In such diagrams, the terms enclosed in ovals or circles refer
to program components that literally appear in programs. Terms enclosed in
boxes refer to program components that require further definition, perhaps
with another syntax diagram. A collection of such diagrams can serve as a
formal definition of a programming language's syntax (although they do not
help distinguish between good and bad programming style!).
Below is the syntax diagram for an "if statement". It is best understood in
conjunction with the syntax diagram for a "statement". In particular, notice
that the diagram doesn't explicitly include the ";" or "{}" delimiters, since
these are built into the definition (syntax diagram) of "statement".
The C++ compiler accepts the program fragment in our example by counting all
of the bold text in
...
...
if (total_test_score < 50)
cout << "You are a failure. You must study much harder.\n";
else if (total_test_score < 65)
cout << "You have just scraped through the test.\n";
else if (total_test_score < 80)
cout << "You have done quite well.\n";
else if (total_test_score < 95)
cout << "Your score is excellent. Well done.\n";
else {
cout << "You cheated!\n";
total_test_score = 0;
}
...
...
as the single statement which must follow the first else.
As far as the C++ compiler is concerned, the following program is exactly the
same as the program in Section 1.5:
#include <iostream.h>
int main()
{
int year_now, age_now, another_year, another_age;
cout << "Enter the current year then press RETURN.\n";
cin year_now;
cout << "Enter your current age in years.\n";
cin age_now;
cout << "Enter the year for which you wish to know your
age.\n";
cin another_year; another_age = another_year - (year_now -
age_now);
if (another_age >= 0)
{
cout << "Your age in " << another_year << ": ";
cout << another_age << "\n";
}
else
{
cout << "You weren't even born in ";
cout << another_year << "!\n"; }
return 0;
}
However, the lack of program comments, spaces, new lines and indentation
makes this program unacceptable.
1.9 Summary
Exercise Sheet 1
Alter the example program so that if "another_age" works out to be more than 150, the screen output is:
Sorry, but you'll probably be dead by [year]!
Test the program with various different inputs from the keyboard.
/* This program prompts the user for the current year, the user's current age, and another year. It then calculates the
age that the user was or will be in the second year entered. */
#include <iostream.h>
int main()
{
int year_now, age_now, another_year, another_age;
cout << "Enter the year for which you wish to know your age.\n";
cin >> another_year;
return 0;
}
Question 3
(More difficult.) Alter your program from question 2 so that it deals with months as well as years, and produces
output such as the following:
Enter the month in which you were born (a number from 1 to 12).
5
Enter the year for which you wish to know your age.
2001
/* This program prompts the user for the current year and month, the user's current age in years and months, and
another year and month. It then calculates the age that the user was or will be in the second year and month entered.
*/
#include <iostream.h>
int main()
{
/* Variables for user input: */
int year_now, month_now, age_now, month_born, another_year, another_month;
cout << "Enter the month in which you were born (a number from 1 to 12).\n";
cin >> month_born;
cout << "Enter the year for which you wish to know your age.\n";
cin >> another_year;
/* Convert everything to months, then do the same calculation as in Program 1.5.1 (some of the brackets in
the following statements aren't strictly necessary): */
return 0;
}
2.1 Identifiers
As we have seen, C++ programs can be written using many English words. It is useful to think of words found in a
program as being one of three types:
1. Reserved Words:. These are words such as if, int and else, which have a predefined meaning that
cannot be changed. Here's a more complete list:
as continue float new signed try
2. Library Identifiers: These words are supplied default meanings by the programming environment, and
should only have their meanings changed if the programmer has strong reasons for doing so. Examples are
cin, cout and sqrt (square root).
3. Programmer-supplied Identifiers: These words are "created" by the programmer, and are typically
variable names, such as year_now and another_age.
An identifier cannot be any sequence of symbols. A valid identifier must start with a letter of the alphabet or an
underscore ("_") and must consist only of letters, digits, and underscores.
C++ requires that all variables used in a program be given a data type. We have already seen the data type int.
Variables of this type are used to represent integers (whole numbers). Declaring a variable to be of type int signals
to the compiler that it must associate enough memory with the variable's identifier to store an integer value or
integer values as the program executes. But there is a (system dependent) limit on the largest and smallest integers
that can be stored. Hence C++ also supports the data types short int and long int which represent,
respectively, a smaller and a larger range of integer values than int. Adding the prefix unsigned to any of these
types means that you wish to represent non-negative integers only.
For example, the declaration
unsigned short int year_now, age_now, another_year, another_age;
Variables of type "float" are used to store real numbers. Plus and minus
signs for data of type "float" are treated exactly as with integers, and
trailing zeros to the right of the decimal point are ignored. Hence "+523.5",
"523.5" and "523.500" all represent the same value. The computer also accepts
real numbers in floating-point form (or "scientific notation"). Hence 523.5
could be written as "5.235e+02" (i.e. 5.235 x 10 x 10), and -0.0034 as "-
3.4e-03". In addition to "float", C++ supports the types "double" and "long
double", which give increasingly precise representation of real numbers, but
at the cost of more computer memory.
Type Casting
the "/" will always be interpreted as real-number division, even when both
"numerator" and "denominator" have integer values. Other type names can also
be used for type casting. For example, "int(14.35)" has an integer value of
14.
Characters
Variables of type "char" are used to store character data. In standard C++,
data of type "char" can only be a single character (which could be a blank
space). These characters come from an available character set which can
differ from computer to computer. However, it always includes upper and lower
case letters of the alphabet, the digits 0, ... , 9, and some special symbols
such as #, £, !, +, -, etc. Perhaps the most common collection of characters
is the ASCII character set
#include <iostream.h>
int main()
{
int number;
char character;
number = character;
return 0;
}
Program 2.2.1
produces output such as
Type in a character:
9
The character '9' is represented as the number 57 in the computer.
We could modify the above program to print out the whole ASCII table of
characters using a "for loop". The "for loop" is an example of a repetition
statement –
Strings
Our example programs have made extensive use of the type "string" in their
output. As we have seen, in C++ a string constant must be enclosed in double
quotation marks. Hence we have seen output statements such as
We will see how the programmer may define his or her own data types. This
facility provides a powerful programming tool when complex structures of data
need to be represented and manipulated by a C++ program.
float number;
Between this statement and the first statement, which assigns “number”, an
explicit value, the value contained in the variable "number" is arbitrary.
But in C++ it is possible (and desirable) to initialize variables with a
particular value at the same time as declaring them. Hence we can write
float PI = 3.1416;
By default, members of an "enum" list are given the values 0, 1, 2, etc., but
when "enum" members are explicitly initialized, uninitialized members of the
list have values that are one more than the previous value on the list:
enum { MON = 1, TUES, WED, THURS, FRI, SAT = -1, SUN };
In this case, the value of "FRI" is 5, and the value of "SUN" is 0.
#include <iostream.h>
int main()
{
float radius = 0;
drawCircle(radius * 2);
cout.setf(ios::fixed);
cout.precision(2);
cout << "The circumference of a circle of radius " << radius;
cout << " is approximately " << 2 * PI * radius << ".\n";
return 0;
}
We have already seen how programs can include variable assignments such as
number = number + 1;
Since it is often the case that variables are assigned a new value in
function of their old value, C++ provides a shorthand notation. Any of the
operators "+", "-", "*", "/" and "%" can be prefixed to the assignment
operator (=), as in the following examples
The first of the above examples may be written in even shorter form. Using
the increment operator "++", we may simply write
number++;
The operator "++" may also be used as a prefix operator:
++number;
but care must be taken, since in some contexts the prefix and postfix modes
of use have different effects. For example, the program fragment
x = 4;
y = x++;
results in "x" having the value 5 and "y" having the value 4, whereas
x = 4;
y = ++x;
In general, assignment statements have a value equal to the value of the left
hand side after the assignment. Hence the following is a legal expression
which can be included in a program and which might be either evaluated as
true or as false:
(y = ++x) == 5
It can be read as the assertion: "after x is incremented and its new value
assigned to y, y's value is equal to 5".
Intuitively, we think of expressions such as "2 < 7", "1.2 != 3.7" and "6 >=
9" as evaluating to "true" or "false" ("!=" means "not equal to"). Such
expressions can be combined using the logical operators "&&" ("and"), "||"
("or") and "!" ("not"), as in the following examples:
The fourth of these expressions is true because the operator "&&" has a
higher precedence than the operator "||". You can check the relative
precedence of the different C++ operators in a C++ programming manual or text
book. But if in doubt use ( ) parentheses, which in any case often make the
program easier to read.
Compound Boolean expressions are typically used as the condition in "if
statements" and "for loops". For example:
...
...
if (total_test_score >= 50 && total_test_score < 65)
cout << "You have just scraped through the test.\n";
...
...
Once again, there is an important technical point concerning Boolean
expressions. In C++, "true" is represented simply as the value 1 (or any
positive integer in some systems), and "false" is represented as the value 0.
This can lead to errors. For example, it is quite easy to type "=" instead of
"==". Unfortunately, the program fragment
...
...
if (number_of_people = 1)
cout << "There is only one person.\n";
...
...
will always result in the message "There is only one person" being output to
the screen, even if the previous value of the variable "number_of_people" was
not 1.
Exercise Sheet 2
1. To convert temperatures written in Fahrenheit to Celsius (Centigrade), you subtract 32, multiply by 5 and then
divide by 9. To convert Celsius to Absolute Value (Kelvin), you add 273.15. Write a program that displays a
temperature conversion chart on the screen as follows:
0 -17.78 255.37
20 -6.67 266.48
40 4.44 277.59
... ...... ......
... ...... ......
300 148.89 422.04
#include <iostream.h>
int main()
{
int fahr = LOWER;
double celsius = 0;
2) Alter the program for question 1 so that it prompts the user for the lowest and highest Fahrenheit temperature
wanted in the table, and also prompts the user for the desired step size between rows of the table (the step size is 20
in question 1). The program should begin by explaining to the user what it does, and should appropriately echo the
user's input before printing the table.
/* This program prints out a conversion table of temperatures, after prompting the user for upper and lower bounds
in Fahrenheit, and the temperature difference between table entries. */
#include <iostream.h>
int main()
{
int fahr = 0;
double celsius = 0;
int lower = 0;
int upper = 0;
int step = 1;
3) Write a program that reads in a character <char> from the keyboard, and then displays one of the following
messages: (i) if <char> is a lower case letter, the message "The upper case character corresponding to <char> is ...",
(ii) if <char> is an upper case letter, the message "The lower case character corresponding to <char> is ...", or (iii) if
<char> is not a letter, the message "<char> is not a letter". You will need to refer to a table of ASCII characters.
/* This program displays upper and lower case versions of any letter typed from the keyboard. */
#include <iostream.h>
int main()
{
char letter = 'a';
return 0;
}
4) Write a program which will raise any number x to a positive power n using a "for loop". (Is there any way to
improve the efficiency of your program?)
/* print answer */
cout << answer << ".\n";
return 0;
}
A natural way to solve large problems is to break them down into a series of sub-problems, which can be solved
more-or-less independently and then combined to arrive at a complete solution. In programming, this methodology
reflects itself in the use of sub-programs, and in C++ all sub-programs are called functions (corresponding to both
"functions" and "procedures" in Pascal and some other programming languages).
We have already been using sub-programs. For example, we used the following "for loop":
...
#include<math.h>
...
...
for (number = 1 ; number <= 10 ; number = number + 1) {
cout.width(20);
cout << number << sqrt(number) << "\n";
}
...
...
The function "sqrt(...)" is defined in a sub-program accessed via the library file "math.h". The sub-program
takes "number", uses a particular algorithm to compute its square root, and then returns the computed value back to
the program. We don't care what the algorithm is as long as it gives the correct result. It would be ridiculous to have
to explicitly (and perhaps repeatedly) include this algorithm in the "main" program.
In this chapter we will discuss how the programmer can define his or her own functions. At first, we will put these
functions in the same file as "main". Later we will see how to place different functions in different files.
Here's a trivial example of a program which includes a user defined function, in this case called "area(...)". The
program computes the area of a rectangle of given length and width.
#include<iostream.h>
/* MAIN PROGRAM: */
int main()
{
int this_length, this_width;
cout << "The area of a " << this_length << "x" << this_width;
cout << " rectangle is " << area(this_length, this_width);
return 0;
}
/* END OF MAIN PROGRAM */
return number;
} /* end of function definition */
/* END OF FUNCTION */
Program 3.2.1
Although this program is not written in the most succinct form possible, it serves to illustrate a number of features
concerning functions:
• The structure of a function definition is like the structure of "main()", with its own list of variable
declarations and program statements.
• A function can have a list of zero or more parameters inside its brackets, each of which has a separate type.
• A function has to be declared in a function declaration at the top of the program, just after any global
constant declarations, and before it can be called by "main()" or in other function definitions.
• Function declarations are a bit like variable declarations - they specify which type the function will return.
A function may have more than one "return" statement, in which case the function definition will end execution as
soon as the first "return" is reached. For example:
double absolute_value(double number)
{
if (number >= 0)
return number;
else
return 0 - number;
}
The parameters in the functions above are all value parameters. When the function is called within the main
program, it is passed the values currently contained in certain variables. For example, "area(...)" is passed the
current values of the variables "this_length" and "this_width". The function "area(...)" then stores
these values in its own private variables, and uses its own private copies in its subsequent computation.
#include<iostream.h>
#include<math.h>
/* MAIN PROGRAM: */
int main()
{
int whole_number;
return 0;
}
/* END OF MAIN PROGRAM */
return product;
}
/* END OF FUNCTION */
By the use of a value parameter, we have avoided the (correct but unwanted) output
Enter a positive integer:
4
The factorial of 4 is 24, and the square root of 0 is 0.
which would have resulted if the function "factorial(...)" had permanently changed the value of the variable
"whole_number".
Reference Parameters
Under some circumstances, it is legitimate to require a function to modify the value of an actual parameter that it is
passed. For example, going back to the program which inputs the dimensions of a rectangle and calculates the area,
it would make good design sense to package up lines 9 to 13 of the main program into a "get-dimensions" sub-
program (i.e. a C++ function). In this case, we require the function to alter the values of "this_length" and
"this_width" (passed as parameters), according to the values input from the keyboard. We can achieve this as
follows using reference parameters, whose types are post-fixed with an "&":
#include<iostream.h>
/* MAIN PROGRAM: */
int main()
{
int this_length, this_width;
get_dimensions(this_length, this_width);
cout << "The area of a " << this_length << "x" << this_width;
cout << " rectangle is " << area(this_length, this_width);
return 0;
}
/* END OF MAIN PROGRAM */
C++ allows polymorphism, i.e. it allows more than one function to have the same name, provided all functions are
either distinguishable by the typing or the number of their parameters. Using a function name more than once is
sometimes referred to as overloading the function name. Here's an example:
#include<iostream.h>
/* MAIN PROGRAM: */
int main()
{
int number_A = 5, number_B = 3, number_C = 10;
cout << "The integer average of " << number_A << " and ";
cout << number_B << " is ";
cout << average(number_A, number_B) << ".\n\n";
cout << "The integer average of " << number_A << ", ";
cout << number_B << " and " << number_C << " is ";
cout << average(number_A, number_B, number_C) << ".\n";
return 0;
}
/* END OF MAIN PROGRAM */
One of the main purposes of using functions is to aid in the top down design of programs. During the design stage,
as a problem is subdivided into tasks (and then into sub-tasks, sub-sub-tasks, etc.), the problem solver (programmer)
should have to consider only what a function is to do and not be concerned about the details of the function. The
function name and comments at the beginning of the function should be sufficient to inform the user as to what the
function does. (Indeed, during the early stages of program development, experienced programmers often use simple
"dummy" functions or stubs, which simply return an arbitrary value of the correct type, to test out the control flow
of the main or higher level program component.)
Developing functions in this manner is referred to as functional or procedural abstraction. This process is aided by
the use of value parameters and local variables declared within the body of a function. Functions written in this
manner can be regarded as "black boxes". As users of the function, we neither know nor care why they work.
Exercise Sheet 3
1
Add 6 appropriate function declarations for
celsius_of absolute_value_of
print_preliminary_message input_table_specifications
print_message_echoing_input print_table
to the following program, and add the 4 missing function definitions, so that it produces output such as that given
below (you may find it helpful to cut, paste and modify the code for the answer to Exercise 2 Sheet 2). Test your
program with various inputs.
/* This program prints out a conversion table of temperatures, after
prompting the user for upper and lower bounds of the table in
Fahrenheit, and
the temperature difference between table entries. */
#include <iostream.h>
0 -17.78 255.37
20 -6.67 266.48
40 4.44 277.59
60 15.56 288.71
80 26.67 299.82
100 37.78 310.93
#include <iostream.h>
#include <iomanip.h>
void print_preliminary_message();
void input_table_specifications(int& lowest_entry, int& highest_entry, int& step_size);
void print_message_echoing_input(int lowest_entry, int highest_entry, int step_size);
void print_table(int lowest_entry, int highest_entry, int step_size);
/* START OF MAIN PROGRAM */
int main()
{
int lower = 0; /* for the lowest Fahrenheit entry in the table */
int upper = 0; /* for the highest Fahrenheit entry in the table */
int step = 1; /* for the difference in Fahrenheit between entries */
return 0;
}
/* END OF MAIN PROGRAM */
/* START OF FUNCTION */
void print_preliminary_message()
{
cout << "This program prints out a conversion table of temperatures.\n\n";
}
/* END OF FUNCTION */
/* START OF FUNCTION */
void input_table_specifications(int& lowest_entry, int& highest_entry, int& step_size)
{
cout << "Enter the minimum (whole number) temperature\n";
cout << "you want in the table, in Fahrenheit: ";
cin >> lowest_entry;
cout << "Enter the maximum temperature you want in the table: ";
cin >> highest_entry;
cout << "Enter the temperature difference you want between table entries: ";
cin >> step_size;
cout << "\n\n";
}
/* END OF FUNCTION */
/* START OF FUNCTION */
void print_message_echoing_input(int lowest_entry, int highest_entry, int step_size)
{
cout << "Tempertature conversion table from " << lowest_entry << " Fahrenheit\n";
cout << "to " << highest_entry << " Fahrenheit, in steps of ";
cout << step_size << " Fahrenheit:\n\n";
}
/* END OF FUNCTION */
/* START OF FUNCTION */
void print_table(int lowest_entry, int highest_entry, int step_size)
{
int fahr;
2
Split your answer program to Question 1 into three files: (i) a main program file, (ii) a header file called
"conversions.h" for the functions "celsius_of(...)" and "absolute_value_of(...)", and (iii) an
implementation file for these two functions. Again, test your program with various inputs.
(EXAMPLE ANSWER: main program file, header file, implementation file)
/* This program prints out a conversion table of temperatures, after prompting the user for upper and lower bounds
of the table in Fahrenheit, and the temperature difference between table entries. */
#include <iostream.h>
#include "conversions.h"
void print_preliminary_message();
void input_table_specifications(int& lowest_entry, int& highest_entry, int& step_size);
void print_message_echoing_input(int lowest_entry, int highest_entry, int step_size);
void print_table(int lowest_entry, int highest_entry, int step_size);
return 0;
}
/* END OF MAIN PROGRAM */
/* START OF FUNCTION */
void print_preliminary_message()
{
cout << "This program prints out a conversion table of temperatures.\n\n";
}
/* END OF FUNCTION */
/* START OF FUNCTION */
void input_table_specifications(int& lowest_entry, int& highest_entry, int& step_size)
{
cout << "Enter the minimum (whole number) temperature\n";
cout << "you want in the table, in Fahrenheit: ";
cin >> lowest_entry;
cout << "Enter the maximum temperature you want in the table: ";
cin >> highest_entry;
cout << "Enter the temperature difference you want between table entries: ";
cin >> step_size;
cout << "\n\n";
}
/* END OF FUNCTION */
/* START OF FUNCTION */
void print_message_echoing_input(int lowest_entry, int highest_entry, int step_size)
{
cout << "Tempertature conversion table from " << lowest_entry << " Fahrenheit\n";
cout << "to " << highest_entry << " Fahrenheit, in steps of ";
cout << step_size << " Fahrenheit:\n\n";
}
/* END OF FUNCTION */
/* START OF FUNCTION */
void print_table(int lowest_entry, int highest_entry, int step_size)
{
int fahr;
3
(This question is similar to Question 2, page 204, Savitch.)
(a) Create a header file "statistics.h" and a corresponding implementation file "statistics.cpp" containing the
functions "average(...)" and "standard_deviation(...)". The functions should return the average and
standard deviation respectively of 1, 2, 3 or 4 real number values. (The standard deviation of the numbers r1, ..., rN
is defined as the square root of the average of the expressions
((r1 - a) x (r1 - a)) , . . . . . . , ((rN - a) x (rN - a)),
where a is the average value of r1, ..., rN.)
Hints: (i) You should take advantage of C++'s facility for polymorphic functions, and overload the function names.
(ii) It is possible to call one function from inside another. (iii) You should be doing plenty of cutting and pasting!
(b) Write a program which tests the functions in "statistics.h" again and again with various inputs until you tell the
program that you are finished. Your program should be able to reproduce the following sample input/output session:
This program tests the functions in the 'statistics.h' header file.
/* This program tests out the functions "standard_deviation()" and "average()" in the header file "statistics.h". */
#include <iostream.h>
#include "statistics.h"
cout << "This program tests the functions in the 'statistics.h' header file.\n\n";
/* test the values and prompt the user again for new values */
for ( ; number_of_values != 0 ; ) // or simply: "while (number_of_values != 0)"
{
if (number_of_values == 1)
test_one_value();
else if (number_of_values == 2)
test_two_values();
else if (number_of_values == 3)
test_three_values();
else if (number_of_values == 4)
test_four_values();
else
cout << "Sorry, the program can only test 1, 2, 3 or 4 values.\n\n";
input_number_of_values(number_of_values);
}
cout << "Finished testing 'statistics.h' header file.\n";
return 0;
}
/* END OF MAIN PROGRAM */
/* FUNCTION TO INPUT 1 NUMBER, THEN PRINT OUT THE AVERAGE AND STANDARD DEVIATION
*/
void test_one_value()
{
double first_value;
/* FUNCTION TO INPUT 2 NUMBERS, THEN PRINT OUT THE AVERAGE AND STANDARD DEVIATION
*/
void test_two_values()
{
double first_value;
double second_value;
/* FUNCTION TO INPUT 4 NUMBERS, THEN PRINT OUT THE AVERAGE AND STANDARD DEVIATION
*/
void test_four_values()
{
double first_value;
double second_value;
double third_value;
double fourth_value;