< previous page page_352 next page >

Page 352
(text box continued from previous page)
time support software (called a thunk) supplied by the compiler. For example, if the name of a variable is passed to a function, the run-time interpreter looks up the name of the parameter in a table of declarations to find the address of the variable. Pass-by-name can have unexpected results. If an actual parameter has the same spelling as a local variable in the function, the function will refer to the local version of the variable instead of the variable in the calling code.
Some versions of pass-by-name allow an expression or even a code segment to be passed to a function. Each time the function refers to the parameter, an interpreter performs the action specified by the parameter. An interpreter is similar to a compiler and nearly as complex. Thus, pass-by-name is the least efficient of the three parameter passing mechanisms. Pass-by-name is supported by the ALGOL and LISP programming languages, but not by C++.
There are two different ways of matching actual parameters with formal parameters, although C++ supports only one of them. Most programming languages, C++ among them, match actual and formal parameters by their relative positions in the two parameter lists. This is called positional matching, relative matching, or implicit matching. A few languages, such as Ada, also support explicit or named matching. In explicit matching, the actual parameter list specifies the name of the formal parameter to be associated with each actual parameter.
Explicit matching allows actual parameters to be written in any order in the function call. The real advantage is that each call documents precisely which values are being passed to which formal parameters.

Designing Functions
We've looked at some examples of functions and defined the syntax of function prototypes and function definitions. But how do we design functions? First, we need to be more specific about what functions do. We've said that they allow us to organize our programs more like our top-down designs, but what really is the advantage of doing that?
The body of a function is like any other segment of code, except that it is contained in a separate block within the program. Isolating a segment of code in a separate block means that its implementation details can be hidden from view. As long as you know how to call a function and what its purpose is, you can use it without knowing how it actually works. For example, you don't know how the code for a library function like sqrt is written (its implementation is hidden from view), yet you still can use it effectively.
The specification of what a function does and how it is invoked defines its interface (see Figure 7-3). By hiding a module implementation, or encapsulating the module, we can make changes to it without changing the main function, as long as the interface remains the same. For example, you might rewrite the body of a function using a more efficient algorithm.

 
< previous page page_352 next page >