CS-120 Lecture 11 Monday, February 9th Admin
Assignments 4a/b due this week. Questions? Assignments 5a/b are posted. Last assignment before the exam. Lab 4 will be posted later this afternoon. Books should be in the bookstore… Study guide for exam should be ready this evening and posted. Abstraction: Functions
First piece: How to call – talked about this on Friday Next piece: How to define Functions are similar to variables in that they have a name that the compiler has to recognize in order to call them properly. Here’s one of the big differences between C and C++ C++ requires that any identifier be declared prior to being referenced Variables must be declared Functions must be either defined or declared (prototyped) C doesn’t require a function to be defined prior to use; it relies on the linker to resolve any undefined functions. Enter the function prototype:
Rules for prototypes: Must be declared in global scope (outside of any other function) Must have a return type, but that type may be void Must have a type for each parameter. Optionally, you can include an identifier as well, but this is not required. Why not? What is the purpose of the prototype? Terminated with a ‘;’ Abstraction: Functions (cont’d)
Purpose of prototype: Provides a defined structure for calls to the function that the compiler can check against. Using the example above, if I made the call: x = MaxOfThree(1,2,3,4); The compiler would give me an error, because I sent too many arguments to the function. It knows this because the prototype defined the function MaxOfThree as taking three integer arguments. The prototype also allows us to define default values for the parameters, but I will get into that later on. Do we have to have a function prototype? Abstraction: Functions (cont’d)
Nope! We can define the function as one step (signature + body), but this must be done prior to any calls to the function. This means, generally, our functions would have to be written in reverse order A calls B, which calls C C would have to be defined before B, which would have to be defined before A. In most programs, this would make the program difficult to read. You wouldn’t know what the big picture program is doing until you’d read all of the nitty-gritty details. What we’d rather do is define the body (code) of the function somewhere below/after/in another file, so that someone reading the code is not distracted by the details of the how, before they read the why. Abstraction: Functions (cont’d)
Definition The function definition contains the code that the function executes. One way to think of this is that each function is a separate program. It has its own code, its own variables, and once it is done executing, it returns to the calling context, possibly sending a value back. Syntax:
Some things to keep in mind: Parameters are just like variables and can be used like them; you do not need to re- declare them Parameters are normally passed to the function as a “copy” of the value used as an argument. This is called “pass-by-value” and is very important to ensure the modularity of functions. Basically, when you call y = sqrt(x), you really don’t want the sqrt() function to change the value that’s in x. Functions are basically “their own little world” when it comes to things like variable names. You can declare any local variable name you want, and it won’t interfere or cause conflicts with local variables in other functions (we’ll talk about local vs. global later this week). It is good practice to only have a single return statement from a function. This is not a requirement! Many times it may make sense to put more than one return statement in a function, and you shouldn’t think it is wrong to do this. However, nearly any time that you would use multiple return statements, you could do it with one instead. Let’s see an example! FuncExample.cpp Abstraction: Functions (cont’d)
Returning from a function: The return statement sends the program execution back to the calling context, right where it left off. One way to think about this is that the function that was executing when another function is called is basically “paused” while the new function executes. When the new function returns, the old function continues from where it was paused. This is how the statements like srand(time(NULL)); work. Abstraction: Return values (cont’d)
void functions: Functions that have the return type “void” do not return a value, and therefore cannot be used inside expressions. These functions are often called by another name in other languages, such as “procedure” in Pascal, since they don’t actually provide a data transformation (although, we’ll see that this is not necessarily strictly true). These functions usually are simply a way of lumping code together and calling it a name that describes the overall task they do. For example, you might have a function called “Setup” which does all of the initialization and setup tasks for your program, such as printing a greeting, rules, help etc. This function makes sense to declare as a void function, because it’s not returning a value based upon some transformation, it’s simply performing a set of tasks that all fall under the “Setup” umbrella. Objectives
At the end of this lecture you should be able to: Recognize and label the pieces of a program that make up a function (call, prototype, definition). Describe why a function prototype is useful and/or needed for the compiler to be able to work properly. Given a function prototype and detailed description, write the definition of that function. Describe the flow of execution when a program reaches a function call. Trace the execution of a program with multiple nested function calls, and determine the values of key variables at the conclusion. Describe what the void keyword means, and how void functions work.