This material discusses:
Often, we need to use one set of code over and over again. Functions allow us to write code once and reuse it many times.
For example, we might use a function to calculate the length of the hypotenuse of a right triangle:
cout << "Enter triangle width: "; cin >> w; cout << "Enter triangle height: "; cin >> h; cout << "The hypotenuse is " << hypotenuse(w, h) << endl;
Using functions can act as documentation (if they are given appropriate
names). Compare the instant recognition of hypotenuse(w,
h) to sqrt(w*w+h*h).
Functions in C++ follow this basic format:
return-type functionName(parameter-list)
{
body
}
int, float) of value is returned. Functions that
don't return a value have a return type of void.
func_name or funcName,
but not func-name (- is not a valid identifier character).
int a, int b, char
ch. If a function takes no parameters, it should have an empty
parameter list ().
The return-type, function name and parameter-list form the header of the function.
The body contains statements to be performed by the
function. You may declare additional variables in the body--such
variables only exist inside the function.
Thus, a complete function might be:
The
For functions (other than those that return nothing, i.e.,
With a
Returning from a function immediately exits the function.
Thus, the output above is never seen if allowed is not
true.
To use a function, you must call it.
Basically, you just give the function's name following by a
If the function has a return type other than
Normally, when you pass parameters to a function (by calling it), the
function gets copies of those values. Thus, any changes you make to
parameters doesn't affect any passed variables. For example:
Whether the formal parameter (i) and the actual
parameter (j) have different names or the same
name--i.e., they are different variables.
This kind of parameter passing is named "call-by-value".
Sometimes, you really do want to change parameters. For example,
here is an unsuccessful swapping function:
To be able to change parameters, you must list them by
reference in the parameter list. Do so by adding ampersands
(
Since functions can only have one return value, call-by-reference
can also be useful when you need to return more than one thing.
For example,
Finally, unlike with call-by-value, where you can pass
literals as parameters:
So far, we have just been giving function definitions for
functions. I.e.,
Note that the prototype looks just like the header of the function
(with a semi-colon at the end).
Although the types of parameters are required, names are not.
I.e., we could have written the prototype as:
A prototype allows the compiler to check that the number and type of
parameters match between the function and its call and to do any
necessary conversion of passed parameters. For example,
When a function definition appears before any call to
that function, the definition acts like a prototype.
We'd like a program that makes change. In other words, given the total
amount of change to be given to a customer, it will tell you how many
dollars and coins to give out.
A run of such a program looks like (things you type are bold):
We have provided a skeleton for this program, makechange.cpp. Fill in the function
prototype, function definition, and function
call for the function
When you are done, compile and run the program to test it.
Hint: Some of the arithmetic operations (e.g., +, -, *, /
(quotient) or % (modulus)) may be useful in the body of the function.
double hypotenuse(double width, double height)
{
double width_squared = width * width;
double height_squared = height * height;
return sqrt(width_squared + height_squared);
}
return statement is used to return a value from a
function.
void),
the syntax is:
return expression;
The expression should either be of the same type as the
function's return type or of a type the compiler can convert
to its return type. For example,
float func1()
{
int a;
...
return a;
}
int func2()
{
int i;
...
return i + 4.0;
}
func1() is ok (since int can be safely
converted to float); however, func2() is not
ok since the reverse is not true.
Note:
Functions that have a non-void return type must return a value under
all circumstances.
void return type, you use return by
itself. If you want the function to just end after the last statement,
no return is needed. For example,
void speakIfAllowed(bool allowed)
{
if (!allowed)
return;
cout << "Hello!" << endl; // Function ends after this statement.
}
(, a comma-separated list of values you are passing to the
function, and a ). For example:
hypotenuse(w, h)
Note:
Types are not listed for a function call.
void, you
may use the return value (you don't have to):
...
double c;
c = hypotenuse(a, b);
cout << "The hypotenuse of a right triangle " << endl
<< "with width=10 and height=2 is "
<< hypotenuse(10, 2) << endl;
int nextInt(int i)
{
i++;
return i;
}
int main()
{
int j = 10;
cout << "Next int is " << nextInt(j) << endl;
}
The output would be "Next int is 11", but j would
still be 10.
void swap1(int i, int j)
{
int temp = i;
i = j;
j = temp;
}
int main()
{
int a = 4, b = 5;
swap1(a, b);
cout << "a is " << a << " and b is " << b << endl;
}
The output is "a is 4 and b is 5"!
&) to each:
void swap2(int &i, int &j)
{
int temp = i;
i = j;
j = temp;
}
The function body is the same as the unsuccessful version. The
function call also looks the same:
int main()
{
int a = 4, b = 5;
swap2(a, b);
cout << "a is " << a << " and b is " << b << endl;
}
but now we get the desired answer "a is 5 and b is 4".
void getNameParts(string fullname,
string &firstname,
string &lastname)
{
...
}
hypotenuse(10, 6)
you really need to pass variables for parameters that are
by reference:
int a = 4, b = 5;
swap2(a, b); // YES
swap2(2, 4); // NO!
double hypotenuse(double width, double height)
{
double width_squared = width * width;
double height_squared = height * height;
return sqrt(width_squared + height_squared);
}
That's fine if the function definition appears before you
call the function:
... hypotenuse(w, h) ...
However, sometimes a function may be defined after
a call to it. Or, the definition may be somewhere else, like in a library.
In such cases, we must provide a function prototype for the
function before it is called. For example,
// prototype
double hypotenuse(double width, double height);
... hypotenuse(w, h) // call
// definition
double hypotenuse(double width, double height)
{
double width_squared = width * width;
double height_squared = height * height;
return sqrt(width_squared + height_squared);
}
double hypotenuse(double, double);
However, parameter names often add to readability and should be
included in most cases.
hypotenuse(w, h, d); // Wrong, only takes 2 parameters!
hypotenuse(4, 5); // Convert to double, then call function.
Note: Header files often contain prototypes. For example,
math.h has prototypes for the functions in the math
library.
% makechange
How much change to make (in cents): 1099
Your change is:
10 dollars
3 quarters
2 dimes
0 nickels
4 pennies
makeChange().