One of the most important features of C++, or of almost any programming language, is your ability to define new functions. You write a large piece of software by breaking it into a collection of small functions, each with a specific purpose.
The general form of a function definition is
R name(arguments) { body }where
R is the type of result that the function returns,
name is the function's name,
arguments is a comma-separated list of the function's arguments. Each argument is given as a type followed by a name.
body is a sequence of statements that preforms the actions that the function needs to do.
return E;indicates that the function is finished and that its result is the value of expression E.
Here are some example functions.
// Return the integer that is one larger than n. int successor(int n) { return n+1; } // Return the larger of x and y. (This is // equivalent to the max function from the // algorithm library, except that larger requires // its arguments to be of type double.) double larger(double x, double y) { if(x > y) { return x; } else { return y; } } // Return the largest of x, y and z. double largest(double x, double y, double z) { return larger(x, larger(y,z)); } // Return true of n is prime and false if n is // not prime. // // Requirement: n > 1. bool isPrime(long n) { //------------------------------------------- // We try potential factors up to the square // root of n, rounded to the nearest integer. //------------------------------------------- long s = (long)(sqrt(n) + 0.5); for(int k = 2; k <= s; k++) { if(n % k == 0) { return false; } } return true; }
As the definition of largest suggests, you should feel free to use the functions that you have defined as tools for defining other functions.
Use your defined function the same way you would a function from the library. For example,
if(isPrime(2*y+1))
{
printf("%i is prime\n", 2*y+1);
}
uses isPrime in a test. Notice that the form of
the argument 2*y+1 is not required to match
the name, n,
used to refer to it in the definition of isPrime.
Only the types must match. For any expression
E of type long, isPrime(E) yields
true if the value of expression E is prime.
The argument name, n, in the definition of
isPrime is just a convenient way to refer to
the number that is passed within the body of isPrime.
When you use a function, you are said to call that function, and expression larger(7,4) is a function call expression.
After seeing a type in front of each argument in a function definition, some students try to write types in function calls too. Do not write types in function calls. For example,
double z = largest(a, b, c);makes sense. But
double z = largest(double a, double b, double c);does not make sense. You are not defining function largest here, so get rid of the types.
Do not try to do anything special to get a function to run. A function call expression automatically runs the function. Sometimes inexperienced programmers are not sure how to get the result of a function, and write something like
isPrime(x); if(isPrime(x)) { ... }believing that expression isPrime(x) in the if-statement refers to the answer produced by the statement just before it. But, since this program contains expression isPrime(x) twice, the function is called twice. The first statement calls isPrime(x) and just throws away its result. Get rid of it.
When a function is called, a new frame is created for it in the run-time stack. That frame holds all of the variables and parameters that the function uses. When the function returns, its frame is destroyed.
It is important to realize that a function's variables are associated with a frame, not with the function itself. When we look at recursion the distinction will become very important.
Define a function sqr(x) that takes a real number x (type double) and returns the square of x (also of type double). For example, sqr(10.0) should return 100.0. Also write a contract for this function. Answer
Without using the abs function, define function absoluteValue(n) that takes an int n and returns its absolute value. Also write a contract for this function. Answer
Define a function isPerfect(n) that takes a positive integer n and yields true of n is perfect and false if not. Also write a contract for this function. See question 3 on the page on while-loops for a definition of a perfect number. Answer
Using your isPerfect function from the preceding exercise, define a function nextPerfect(n) that returns the smallest perfect number that is greater than n. Assume that n is a positive integer. For example, nextPerfect(1) = 6. Answer
Suppose that function dbl is defined by
int dbl(int x) { return 2*x; }Is the following allowed in C++?
int z = 10; int y = dbl(int z);Answer
Is the following function definition allowed?
int dbl(int x) return x*x;Answer
Rewrite the following two statements as one statement. Assume that function f has no side-effects and that variable q is not needed for anything else.
int q = f(w); int r = f(q);Answer
Suppose function g is defined as follows.
int g(int n) { if(n > 3) { return 0; } else { return 2*n+3; } }What is the value of expression g(3)? Answer
Using function g from the preceding problem, what is g(g(3))? Answer
Write a C++ definition of function seconds(ms), which takes an integer value ms representing some number of milliseconds (thousandths of a second) and returns a real number that is ms in seconds. For example, seconds(2001) = 2.001. Answer