Sei sulla pagina 1di 10

Chapter 8 Functions

Learning Objectives
After studying this chapter a student should be able to: Explain what a function is. Explain the role of a functions parameters. Explain the role of a functions return value. Differentiate between function input/output and input/output via the console. Identify the parts of a function denition function header, body, return type, parameters, and name. Identify and author C/C++ language syntax to declare a function. List the order in which functions must be declared knowing only which function calls which. Author appropriately descriptive comments to document a function. Explain what it means for a parameter to be pass-by-value. Trace, by hand, the execution of a C/C++ program into and through a function call. Describe, in plain English, the behaviour of a computer program when a function call is performed. Identify and author C/C++ language syntax to declare a function with no parameters. Explain the role and behaviour of the return statement. Identify and author C/C++ language syntax to declare a procedure. Differentiate between situations in which a function should be declared instead of a procedure, and vice versa. Functionally decompose a problem, or algorithm, in a sensible manner.

8.1

Introduction

A function is an encapsulation of an algorithm (we discussed encapsulation in Chapter 1). It is a way of referring, by name, to a set of instructions which accomplish a specic task. We distinguish between dening a function, and using a function. The denition does not cause the function to do anything; its just a set of instructions, a potential, waiting to happen. The function only gets set into action if it is called by some other part of the program.
D.Neilson, M.Horsch, CMPT 111: Introduction to Computer Science and Programming

59

CHAPTER 8. FUNCTIONS

A function can be called many times in a single program, and also by many different programs. Recall from Chapter 5, we discussed mathematical functions like sin and pow. We did not reveal the algorithms for these functions, but we showed how they can be used when needed. Functions allow software developers to organize their programs. Without a way to organize them, very large programs would be impossible to write, let alone x or improve. Developers can put code to do this here in this function, and code to do that in that other function. Functions also allow software developer to solve very complex problems. If a complex problem can be separated into independently solvable sub-problems, it is easier to solve. A function can be seen as the solution to a sub-problem, so the developer builds the solution to the complex task by building functions that solve the various sub-problems. This technique is very powerful, and is called functional decomposition. A function that solves one very specic task is useful, but a function that can solve many tasks is more useful. For example, the function sin can compute the sin of any oating point number. You may think that this is one task, but imagine a function that could only compute the sin of positive angles; or only angles between 0 and 2 ; or only the very specic angle /4. All of these are possible, and hopefully it is obvious that the rst is the most useful, and the last is almost useless. But it also works the other way. A function that computes sin of any angle is useful, but a function that computed the value of sin would not be more useful if it also caused an animation of a dancing cow to appear on the computer screen. If we accept a function as an encapsulated algorithm, then we have to give it input and let it produce output. The primary way we will give a function input is through its parameters (dened below). The primary way for a function to produce output is through its return value (dened below). When functions communicate with each other, it is through the parameters and return values. We are going to repeat that last bit because is is important. If you want your program to know some piece of information/data, then you have to tell it through a parameter. Similarly, if you want your function to tell its caller some piece of information, then it has to be told as the functions return value. Occasionally, a function may use cin or cout to communicate to the user, but functions cannot communicate to each other using the console. The console is not a bulletin board! We have already shown you a little of how to use functions that are provided for you through libraries of code. All that remains is to show you how to dene, and use, your own functions. A function denition looks like this:
Description : Generate a Input : A lower B upper Output : r e t u r n s Assumptions : A< B

random i n t e g e r i n t h e range {A, A+1 , . . . , B } i n c l u s i v e bound on t h e range bound on t h e range . ge ner at ed random value

/ i n t randomRange ( i n t A, i n t B ) { // See documentation f o r c s t d l i b f o r rand ( ) f u n c t i o n r e t u r n ( rand ( ) % ( BA+ 1 ) ) + A; }

60

D.Neilson, M.Horsch, CMPT 111: Introduction to Computer Science and Programming

CHAPTER 8. FUNCTIONS

A function denition contains ve parts. Well discuss them briey here, and then in more detail as this chapter progresses. 1. A comment block (starting with /* and ending with */ 10 lines later, in this example) that tells the reader what the functions purpose is, what input it requires, and what output it provides. The comment block here is very detailed, and covers everything a reader would need to know. A professional software developer would put at least this much effort into documentation. 2. The function header is the line that reads int randomRange(int A, int B). It contains all of the information that a programmer needs to know to call the function. The header is made up of 3 parts, in order from left to right: The return data type is the type of the value that is returned by the function. This example function returns a value with the int data type. Following the return data type is the functions name. The name of a function follows the same naming rules as variables. In this example, the name of the function is randomRange. Next comes parentheses that contain a comma-separated list of the functions parameters. This example has two parameters: A and B, both of type int. The return type always appears rst! Then the function name, then the parameter list. Note that there is no semi-colon at the end of the function header when it is a part of a function denition. 3. Finally, the function body is the block that appears after the header. This block is the program-code that is executed when the function is called. The code in the body may use the function parameters however you wish, and must provide a value for the function to return through a return statement. A function denition must appear before any program code that uses it. This is consistent with the dene-before-use approach that C is based on. For example, if function A calls function B , then the denition of function B must appear before the denition of function A. Finally, a function denition must not be within any other programming construct. Heres a longer example. Notice that the function randomRange() is called in the function playerLives(). Therefore, the function randomRange() is dened rst. Notice also that the function playerLives() is called in the main program, so it is dened before main() (but after randomRange().

# i n c l u d e < iostream > # i n c l u d e < c s t d l i b > // For srand , and rand # i n c l u d e <ctime > // For time using namespace s t d ;

/ Description : Generate a random i n t e g e r i n t h e range [A, B ] , i n c l u s i v e Input : A lower bound on t h e range B upper bound on t h e range . Output : r e t u r n s ge ner at ed random value Assumptions : D.Neilson, M.Horsch, CMPT 111: Introduction to Computer Science and Programming

61

CHAPTER 8. FUNCTIONS A< B / i n t randomRange ( i n t A, i n t B ) { // See c s t d l i b documentation f o r rand ( ) f u n c t i o n r e t u r n ( rand ( ) % ( BA+ 1 ) ) + A; } / Description : Randomly decide i f t h e p l a y e r l i v e s or d i e s . P r i n t a message i n d i c a t i n g s u c c e s s i f they l i v e . Input : whichPassage word d e s c r i b i n g t h e passage ( ex : f i r s t , dark ) Output : r e t u r n s t r u e i f t h e p l a y e r l i v e s on , f a l s e i f he/she d i e s / bool p l a y e r L i v e s ( s t r i n g whichPassage ) { / P l a y e r has a 50% chance t o s u r v i v e t h e room . Can determine whether t h e p l a y e r s u r v i v e s by g e n e r a t i n g a uniformly d i s t r i b u t e d random number between 1 and 1 0 0 . I f t h e number i s b i g g e r than 100 ( s u r v i v a l r a t e ) then t h e p l a y e r l i v e s . / i n t randomRoll = randomRange ( 1 , 1 0 0 ) ; i f ( randomRoll > 5 0 ) { cout << You got through t h e << whichPassage << passage . << endl ; return true ; } return f a l s e ; } i n t main ( ) { // Seed t h e random number g e n e r a t o r srand ( time ( 0 ) ) ; // P r i n t t h e i n t r o cout << You awake i n a dimly l i t room a f t e r a n i g h t o f d r i n k i n g << with some dwarves . << endl << A grungy l o o k i n g man i s i n t h e room with you . He l o o k s << up a t you , as ks << endl << \ Dwarves got you too ? \ , g e s t u r e s a t a passage i n << t h e e a s t wall , << endl << and sa ys \ Out s t h a t way . Good l u c k . \ << endl << endl << The pass ages a r e p i t c h b l a c k . You a r e l i k e l y t o be e a t e n << by a grue . << endl << endl ; // Play t h e game i f ( p l a y e r L i v e s ( f i r s t ) && p l a y e r L i v e s ( s t i c k y ) && p l a y e r L i v e s ( smelly ) && p l a y e r L i v e s ( slimy ) ) { cout << C o n g r a t u l a t i o n s , you have made i t out a l i v e ! << endl ; cout << The barkeep i s w a i t i n g f o r you with your b i l l from << l a s t n i g h t . << endl ; } else

62

D.Neilson, M.Horsch, CMPT 111: Introduction to Computer Science and Programming

CHAPTER 8. FUNCTIONS

cout << You have been e a t e n by a grue . << endl ; } return 0;

We strongly encourage you to type this program out, and use a debugger to investigate how it works.

8.1.1

The function main()

If youve been following along, then you will have noticed that weve been using a function called main() since the rst C++ program we showed you. This is a special function in one sense: When your program is started, the operating system on the computer starts your program by calling main(). When your program is nished, the last thing it should do is return a value to the operating system. In CMPT111, it is good enough to return 0 all the time, but in advanced courses, you may learn about reasons to return other values. All C and C++ programs must have one, and only one, main() function. It is dened in the language that the main() function is the place that your program will always begin executing. The function main() is not special in any other way. Its just a function.

8.1.2

Function Documentation

Recall that comments are completely ignored by the compiler; so, strictly speaking, the comment block immediately before the function header is not required for a program that works correctly. However, it is very good programming practice to include a comment block at the start of every function denition that, at a minimum, contains: a description of what the function does, a brief description for each input and output, and any assumptions or restrictions placed on the input (for example, a sine function might require an angle be provided in radians). The intent of this comment block is to provide all of the information that a programmer will require to be able to understand what your function does, and how they can use your function. A good programmer documents everything they write. A poor programmer forces the readers to gure things out on their own. An excellent programmer documents the functions before they are actually written, as part of the design process.

8.1.3

Function Parameters

A functions parameters are variables available within the function that are automatically initialized when the function is called; they are initialized to contain the values of the arguments (recall that we call the data provided in the parentheses of a function call the arguments to the function) that the function was called with. There are two kinds of parameters in the C language: pass-by value parameters, and pass-by-reference parameters. Both kinds of parameters can provide variables with values for you to use in a function, but they do so in different ways. We are going to discuss pass-by-value parameters now, and revisit pass-by-reference parameters when we discuss arrays in Chapter 11.
D.Neilson, M.Horsch, CMPT 111: Introduction to Computer Science and Programming

63

CHAPTER 8. FUNCTIONS

Pass-by-value Parameters A pass-by-value parameter (PBV) copies a data value, that was provided as an argument when the function was called, into a new variable within the function; the name of this variable is the name provided in the declaration for the parameter. The argument for a PBV parameter can be any kind of data value (a variable, a literal, an expression, a function call, et cetera) because a PBV parameter makes a copy of the data value provided for it. For example, consider the randomRange function provided above. Both of the parameters to this function are PBV parameters; for now, all functions that you write will have pass-by-value parameters. So, if you call this function, say with randomRange(0, 100), then the following happens: 1. 2. 3. 4. Execution pauses exactly where the function call is made. A new environment is set up for randomRange to run in. Variables A and B are created in this new environment. The value 0 is copied into this new variable A (the rst argument goes to the rst parameter). 5. The value 100 is copied into this new variable B (the second argument goes to the second parameter). 6. Execution of randomRange begins. Note that the 0 and 100 used as arguments in this example function call could have been any type of data value, and the behaviour would have been identical (with the different data values used instead, of course). When the return statement is reached in randomRange then execution of randomRange halts, and the variables A and B that were created for the run of randomRange will be destroyed (losing whatever values were in them in the process). No Parameters The C language allows you to write functions that do not have any parameters. Functions with no parameters are useful when you want to do things such as printing out a message to the user, asking for and reading a data value from the console, et cetera. To declare a function with no parameters you can leave the list of parameters blank (the parentheses are still required). When calling a function that has no parameters, you must still provide the parentheses after the function name, but there is nothing within them. For example, this function:

float getInterestRate () { float rate ; cout << P l e a s e e n t e r t h e y e a r l y i n t e r e s t r a t e : ; c i n >> r a t e ; return rate ; }

could be called like this:

interestRate = getInterestRate ( ) ;

64

D.Neilson, M.Horsch, CMPT 111: Introduction to Computer Science and Programming

CHAPTER 8. FUNCTIONS

8.1.4

The return Statement

The return statement inside of a function does three things: It provides the data value that is going to be returned by the function. It immediately halts the execution of the function. It causes execution of the program to resume at the place where the function was called.

The data value provided in the return statement must be the same data type as the return data type of the function; type conversion, such as changing a oat to an int, will be done automatically if possible. This data value may be provided in any way (via: a variable, an expression, another function call as part of an expression, et cetera). Please make note of the syntax used for the return statement. The syntax is the word return followed by a space, then the data value to be returned, and the statement is terminated with a semi-colon. The data value may be in parentheses, if you desire. All functions must return a value using a return statement.

8.2

Procedures

/ Description : P r i n t s out t h e given y e a r l y i n t e r e s t r a t e as p a r t o f a f o r m a t t e d string . Input : r a t e y e a r l y i n t e r e s t r a t e , i n p e r c e n t Output : none / void p r i n t I n t e r e s t R a t e ( f l o a t r a t e ) { cout << The y e a r l y i n t e r e s t r a t e i s << r a t e << % << endl ; return ; }

The data type void is a special data type that, quite literally, means nothing think of the phrase staring into the void. A function may use void for its return data type; we will call a function with a void return type a procedure to differentiate it (you could also call it a void function), but everything we have discussed about functions also holds true for procedures. You should use a procedure when you design a sub-task that does something, but does not calculate any sort of value to return. For instance, you might want to have a sub-task that prints out instructions for how to use your program; such a sub-task would print out text, but does not calculate any value for the program to use. In a procedure, the syntax of the return statement is slightly altered. Procedures have a void return data type, and so they return nothing. As a result, the return statement in a procedure does not include a value (there is no value to return!), and is written simply as the word return followed by a semi-colon. For example:

Since a procedure does not actually return a value, the return statement is not always required in one. There is an implied return statement at the end of the body of a procedure; if execution reaches the end of the procedure, then the procedure will return. So, the above example can also be written as:
65

D.Neilson, M.Horsch, CMPT 111: Introduction to Computer Science and Programming

CHAPTER 8. FUNCTIONS / Description : P r i n t s out t h e given y e a r l y i n t e r e s t r a t e as p a r t o f a f o r m a t t e d string . Input : r a t e y e a r l y i n t e r e s t r a t e , i n p e r c e n t Output : none / void p r i n t I n t e r e s t R a t e ( f l o a t r a t e ) { cout << The y e a r l y i n t e r e s t r a t e i s << r a t e << % << endl ; }

and the behaviour of it is absolutely identical to the example with the return statement. In truth, the only reason you will ever need a return statement in a procedure is when you want to halt the execution of the procedure before the end of its body. Some opinions hold that a function should have exactly one return statement, and that a procedure should have no explicit return statements. This kind of dogmatic teaching is intended to prevent novices from developing bad habits. This should convince you that you need to understand the use of return very carefully, so that you can decide whether to be dogmatic yourself. The second author is dogmatic in this respect.

8.3

Common Pitfalls

There are some common mistakes that we see beginner programmers make with functions in the C language. We include them here for your information, and in the hopes that if you do make one of these mistakes then you will have an easier time nding the source of the problem.

8.3.1

Additional Semi-colon

There is no semi-colon after the function header in a function denition. Recall that the semi-colon separates whatever comes before from whatever comes after. So, placing a semi-colon after the function header will separate the header from the body, which is probably not intended (functions are not zombies!).

8.3.2

Misplaced Declaration

void func1 ( i n t x ) { i n t func2 ( ) { return 1; } }

A function denition in the C language cannot be placed within any other programming construct another function denition, a block of code, et cetera. So, denition similar to any of the following are not allowed in C:

66

D.Neilson, M.Horsch, CMPT 111: Introduction to Computer Science and Programming

CHAPTER 8. FUNCTIONS void func1 ( i n t x ) i n t func2 ( ) { return 1; } { }

8.3.3

Must Declare Before Use

A function denition must appear in your program code before any calls to the function. The compiler for the C language reads your programs source code from the top of the le, and works its way down. Furthermore, it does not know what your function is until you tell it with a function denition. So, if it encounters a call to your function, and you have not declared it above that point in your source le then the compiler will have an error.

8.3.4

No Types When Calling A Function

The return data type, and data types of a functions parameters are required when declaring a function. Once a function has been declared, the C compiler will remember what the return type, and parameter types are. So, when calling a function, you do not include the data types of the values you are passing to it; the C compiler can remember. Thus, for example, the randomRange function that we declared above would be called with something like the following (a, b, and value are all int variables that have already been declared, and initialized):
value value value value = = = = randomRange ( a , b ) ; randomRange ( 0 , b ) ; randomRange ( a , 1 0 0 ) + 2 0 ; 5 randomRange ( a +10 , b + 1 0 0 ) ;

not any of the following:


value value value value = = = = randomRange ( i n t a , i n t b ) ; i n t randomRange ( i n t a , i n t b ) ; i n t randomRange ( a , b ) ; randomRange ( 0 , i n t b + 2 ) ;

8.3.5

Declaring Variables as Function Parameters

A surprising (to us), but common, misconception among beginners is the idea that all of the variables for a function must be declared as parameters. This could not be further from the truth. The code block that is a part of a function denition can contain completely new variable declarations, as well as if statements, loops, printing and reading actions, arithmetic, et cetera. Anything you need (except another function denition). The parameters to a function are only for providing data values to the function. If you need to have some place to store values created by the function, then feel free to declare as many variables inside the function body as you wish.
D.Neilson, M.Horsch, CMPT 111: Introduction to Computer Science and Programming

67

CHAPTER 8. FUNCTIONS

8.4

What the heck is a grue?

What light through yonder Google breaks...

68

D.Neilson, M.Horsch, CMPT 111: Introduction to Computer Science and Programming

Potrebbero piacerti anche