Chapter 3 Function Basics 0. Introduction This chapter shows how to use standard functions provided by the development system libraries, then shows the student how to write functions to take care of situations not covered by library functions. During this last task, the chapter shows how to use local variables and value parameters. Reference parameters are deferred to the next chapter. Finally, scope rules are treated. The idea of function is central to programming, whether Object Oriented Programming or Procedure Oriented Programming. If the paradigm is Procedure Oriented Programming, the algorithm at hand is decomposed into a hierarchical set of functions. If paradigm is Object Oriented Programming, the function members of the classes still must be coded. The material in this chapter will be familiar to anyone who has programmed in any other language. The differences between functions in C++ and other languages will be treated in Chapter 4.
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Chapter 3
Function Basics
0. Introduction
This chapter shows how to use standard functions provided by the development system
libraries, then shows the student how to write functions to take care of situations not
covered by library functions. During this last task, the chapter shows how to use local
variables and value parameters. Reference parameters are deferred to the next chapter.
Finally, scope rules are treated.
The idea of function is central to programming, whether Object Oriented Programming or
Procedure Oriented Programming. If the paradigm is Procedure Oriented Programming,
the algorithm at hand is decomposed into a hierarchical set of functions. If paradigm is
Object Oriented Programming, the function members of the classes still must be coded.
The material in this chapter will be familiar to anyone who has programmed in any other
language. The differences between functions in C++ and other languages will be treated
in Chapter 4.
1. Outline of topics in the chapter
3.1 Predefined Functions
Predefined Functions That Return a Value
Predefined void functions
A Random Number Generator
3.2 Programmer-Defined Functions
Defining Functions that Return a Value
Alternate Form for Function Declaration
Instructor’s Resource Manual for Savitch Absolute C++ 04/07/23 Page 2Chapter 3 Function Basics
Functions Calling Functions
Functions that Return a Boolean Value
Defining void Functions
Return Statements in void Functions
Preconditions and Postconditions
main is a function
Recursive Functions
3.3 Scope Rules
Local Variables
Procedural Abstraction
Global Constants and Global Variables
Blocks
Nested Scopes
Variables Declared in a for Loop
2. General remarks on the chapter
In this chapter, the student begins to learn the tools that will be used to build the members
of the classes, that is, the actions that the classes will take. This involves the tool of
divide and conquer, or stepwise refinement. This tool involves, in its simplest form,
determining subproblems of a nature that, once the subproblems are solved, all that
remains of the original problem is fitting the solutions to the subproblems together. The
top down design tool shows how to recognize subproblems and solve them in such a way
that they fit together automatically, making the last step trivial.
Procedural Abstraction and Information Hiding
David L. Parnas, circa 1972, introduced the notion of information hiding. In this chapter,
we see information hiding in the notion of procedural abstraction. Procedural abstraction
is probably the most important idea in this chapter. If the student does not internalize the
Instructor’s Resource Manual for Savitch Absolute C++ 04/07/23 Page 3Chapter 3 Function Basics
notion that how a task is done should be hidden, with only what is done being revealed,
that student, as a programmer, is crippled. Code written by such a programmer is likely to
be difficult to read and unmaintainable.
Predefined Functions.
C++ requires that every object used in a program be declared prior to any use of the
object. Hence, all functions must be declared prior to use. Predefined (library) functions
are declared in standard header files. Use of predefined (library) functions requires
inclusion of the header files that contain the declarations of these functions. Function
declaration is the C++ name for what ANSI C calls 'prototype'. We will use the term
function declaration, though there is much literature that refers to function declarations as
prototypes.
Potential Problems with Header Files
It is important that the student understand that the #include commands are carried out
by the preprocessor, a part of the C++ compiler that is not smart. The command
#include <filename>
expects the name of the file to contain exactly the characters between the < and the >,
including any spaces. In this include statement,
#include < iostream>
the preprocessor thinks the file name begins with a space followed by the characters of
the name iostream. The preprocessor does not find the header file (no header file has a
name that starts with a space.) This another of the “hard to find” errors that look right.
If you have used the .h header files in C or early C++, you will find that the older header
files have been replaced. The files that did have a .h extension have been replaced by files
with the name composed of the old name with the .h stripped off and prefixed by a ‘c’.
For example, the math.h file has been replaced in C++ by cmath, and stdlib.h has
been replaced by cstdlib. The files specific to C++ such as iostream.h and
iomanip.h are now iostream and iomanip. The C++ Standard specifies that
Instructor’s Resource Manual for Savitch Absolute C++ 04/07/23 Page 4Chapter 3 Function Basics
implementers should arrange for header files without the .h to put their names into
namespace std and the header files without the .h should put their names into the
global namespace. Some caveats: Not all implementations follow the standard in this
respect. Not all implementations have the new files. Most implementations retain the
older files (with the .h extension, names in the global namespace) to avoid breaking older
software. I strongly recommend using the newer C++ features.
Some Possible Errors:
A type of problem my students have is computing an arithmetic average using integer
division (which truncates). Student code typically does the integer division first, then
casts the integer quotient to double.:
double average;
int sum, count;
average = static_cast<double>(sum / count);
instead of this
double average;
int sum, count;
average = static_cast<double>(sum) / count;
It is hard for the student programmer to see this error, as it looks right. Encourage the
students to help debug each other's code. While there is the very real risk of the student
copying code from one another, in my opinion, the enhancement to learning from the
debugging effort is worth the risk.
Another problem the student may encounter is writing a prototype with different return
values but having the same signature such as:
int avg(int s1, int s2, int s3, int s4);
and
double avg(int s1, int s2, int s3, int s4);
The following error message from g++ is clearer than most compiler messages. The
conflict is between the return types:
g++ Prb.cc
In function `double avg(int, int, int, int)':
38: conflicting types for `double avg(int, int, int, int)'
Instructor’s Resource Manual for Savitch Absolute C++ 04/07/23 Page 5Chapter 3 Function Basics
10: previous declaration as `int avg(int, int, int, int)'
Compilation exited abnormally with code 1
Encourage the student to learn the messages your compilers give for the various kinds of
errors.
Increment Operators and Order of Evaluation
Side effects can be evil, particularly when the same variable is affected by a side effect
and the result depends on the order of evaluation. There are only three places in C++ (that
I know of) where the order of evaluation is guaranteed, regardless of side effects. The
arguments to the && operator, the || operator and the comma operator are guaranteed
by the C++ Standard to be evaluated left to right. (But be careful. Your compiler may not
comply with the standard in this regard.) The C++ Standard states that code written that
depends on the order of evaluation of terms in an expression, or of function arguments, is
incorrect. Most compilers do not catch this error. The code will work until you compile
your code with another compiler that evaluates the expressions in a different order. Then
you may find that the program gives different results than you expect. If you are
fortunate, you will find this during testing. If not, a client who is using your code on the
alternate platform will get bad answers.
Example:
//sideEffect.cpp
#include <iostream>
using namespace std;
int main()
{
int x = 2, y;
y = ++x + (++x)*(++x);
cout << " y " << y << endl;
return 0;
}
Instructor’s Resource Manual for Savitch Absolute C++ 04/07/23 Page 6Chapter 3 Function Basics
When compiled with either the MS VC++ 6.0 or BCC 5.5 command line compiler, the
output is 30. This is unreasonable. I do not know why, except that this is illegal code and
the compiler is permitted to do literally anything the compiler author wishes.
Predefined void functions
From the outset it is important that the students understand several
points about void functions. A void function does not return a value.
While a return; statement is allowed, a return; statement is not
necessary, and a return; statement cannot have an argument in
void functions. The call to a void function is an executable statement.
The result of a call to a void function may not be assigned to a
variable. (Technically, a void function's value at execution is not an r-
value.) Execution of a return; statement terminates the function, with
control being returned to the caller. Finally, any code after a return
statement is not executed. A call to a function with no arguments must
have the parentheses following the function name, in contrast to
Pascal, where the function name is sufficient.
For details, read the sections 7.2 and 7.4 of Ellis and Stroustrup, The
Annotated C++ Reference Manual, Addison Wesley, 1991, reprinted
with corrections 1994, ISBN 0-201-5149-1, and sections 11.3.1-11.3.3
in Stroustrup, The design and Evolution of C++ Addison Wesley, 1994
reprinted with corrections, May 1994, or Stroustrup, The C++
NB: adjustment only occurs for complete 2-year interval after 28
age = 29, no adjustment
30 <= age < 32, 1/10 inch adjustment.
Use a function for each calculation. Allow repetition at user option.
Now let's make some declarations:
int height; // inches
int weight; // lbs
int age; // years
double jacketSize; // inches at chest
double waist; // inches at waist
double hatSize;
Hat Size Calculation:
hat size = 2.9 * double(weight) / height;
The cast is clearer, but is not strictly necessary. The weight would be promoted
automatically when multiplication by 2.9 occurs. (This is why the 2.9 is first!)
Jacket Size Calculation:
jacket = double(height) * weight / 288
if (age > 40)
jacket = jacket + (age - 30)/10 * 0.125;
Instructor’s Resource Manual for Savitch Absolute C++ 04/07/23 Page 15Chapter 3 Function Basics
This depends on the behavior of the C/C++ language to obtain the results required. The
(age-30/10) arithmetic will be done as int, since there is nothing to require type
change. The int result will be then converted to double in the multiplication by the 0.125
(which is 1/8 as a decimal.)
Waist Size Calculation:
size = weight/5.7;
if (age>=30)
size = size + (age - 28)/2 * 0.1;
Again, the weight will be converted to double in the division by 5.7. The expression,
(age - 28)/2, will be computed as an int, then be promoted to double in the
multiplication by 0.1.
//problem: Clothes size calculation:
//given height (inches) weight (pounds) and age (years)
//compute jacket size, waist size, in inches, and hat size:
//returns hat size in standard hat size units
#include <iostream>
using namespace std;
double hatSize (int height, int weight)
{
return 2.9 * double(weight) / height;
}
//returns jacketSize in inches at the chest
double jacketSize (int height, int weight, int age)
{
double jacket = double(height) * weight / 288;
if (age > 40)
jacket = jacket + (age - 30)/10 * 0.125;
return jacket;
}
Instructor’s Resource Manual for Savitch Absolute C++ 04/07/23 Page 16Chapter 3 Function Basics
// returns waist size in inches
double waistSize (int height, int weight, int age)
{
double size = weight/5.7;
if (age >= 30)
size = size + (age - 28)/2 * 0.1;
return size;
}
int main()
{
int height, weight, age;
double hat, jacket, waist;
char ans;
do
{
cout << "Give me your height in inches, weight in "
<< "pounds, and age in years" << endl
<< "and I will give you your hat size, jacket "
<< " size(inches at chest)" << endl
<< "and your waist size in inches." << endl;
cin >> height >> weight >> age;
hat = hatSize (height, weight);
jacket = jacketSize (height, weight, age);
waist = waistSize (height, weight, age);
cout.setf(ios::showpoint);
cout.setf(ios::fixed);
cout.precision(2);
cout << "hat size = " << hat << endl;
cout << "jacket size = " << jacket << endl;
cout << "waist size = " << waist << endl;
cout << endl
<< "enter Y or y to repeat, “
<< “any other character ends." << endl;
cin >> ans;
} while ('Y' == ans || 'y' == ans);
return 0;
}
Instructor’s Resource Manual for Savitch Absolute C++ 04/07/23 Page 17Chapter 3 Function Basics
A typical run follows:
Give me your height in inches, weight in pounds, and age in years
and I will give you your hat size, jacket size (inches at chest)
and your waist size in inches.
69 185 50
hat size = 7.78
jacket size = 44.57
waist size = 33.56
enter Y or y to repeat, any other character ends.
y
Give me your height in inches, weight in pounds, and age in years
and I will give you your hat size, jacket size (inches at chest)
and your waist size in inches.
67 200 58
hat size = 8.66
jacket size = 46.78
waist size = 36.59
enter Y or y to repeat, any other character ends.
n
17:08:55:~/AW$
6. Average and standard deviation of scores
The problem as stated in the text requests a problem that is impossible to do within the
elements of C++ available in the chapter. See the errata on the text’s web site, URL:
http://www.aw.com/savitch.
Problem as stated in the text:
Write a function that computes the average (technically, the arithmetic mean) and
standard deviation of four scores, s1, s2, s3, and s4. The average is
a = = s1 + s2 + s3 + s4;
The standard deviation, stdDev1, is the square root of the average of the squares of the
differences of the s values and the average, a.
1 These differences are often called the deviations from the mean, and the standard deviation is then the square root of the mean of the squares of the deviations from the mean:
Instructor’s Resource Manual for Savitch Absolute C++ 04/07/23 Page 18Chapter 3 Function Basics