previous section | next sectionWeek 10: Functions III
Section 2: When to Use Value-Returning Functions
There are two questions that come up regarding how to use value-returning functions well. The first is when to use them. Notice that value-returning functions are completely optional. We could easily write all of our code without them. We can always use the pass-by-reference mechanism to pass values back to the calling function instead of making the function a value-returning function. On the other hand, we could also write all of our code without void functions, using only value-returning functions. So why do we have two types?
The answer is that having two options for how to call a function often allows us to write cleaner code. For example, if we didn't have value-returning functions, then instead of
cout << pow(2,3) << endl;
we would have to write
pow(2,3,answer);
cout << answer << endl;However, using value-returning functions at the wrong time can result in code that, while perhaps more succinct, is in fact less clear. The rules for when to use a value-returning function and when to use a void function are far from unanimous. The rules I'm going to give you are rules you should follow for this class (assuming you care about your grade). In the future you will have to make your own decision about what is a good use of value-returning functions.
For this class, the rule for when to use a value-returning function is:
Use a value-returning function if and only if the function determines a SINGLE result based ONLY on the function's parameters, AND DOES NOTHING ELSE.
One result of this rule is that a value-returning function should never have a cin or a cout statement, since that would violate the "AND DOES NOTHING ELSE" part of the rule. Having a cin statement might also imply that the "based only on the function's parameters" part of the rule is about to be violated, since the value read by the cin statement might be used later in the function to determine the result of the function. Another result of this rule is that a value-returning function should never have a pass-by-reference parameter, since having a pass-by-reference parameter would mean that the function is determining a value to be passed back to the calling function IN ADDITION TO the value that is being returned with the return statement, thus violating the "determines a SINGLE result" part of the rule. If you find yourself with a value-returning function that has a pass-by-reference parameter, you should change it into a void function that has two pass-by-reference parameters.
The rest of section 2 explains the reasoning behind this rule. If you get lost, it's ok. Just focus on understanding how to apply the rule. But for those of you who are interested: the reasoning behind this rule is that a value-returning function is intended to be used like an expression. When we use an expression, we don't expect anything to happen besides the expression getting evaluated. For example, if we said
cout << x * y << endl;
and then after the statement was executed x ended up with a different value, or the words "hello there" got printed on the screen during evaluation of the expression
x * y, that would be bad. In the same way, when we saycout << pow(2,3) << endl;
we don't want anything to happen during the execution of
pow except we want the expression pow(2,3)to get evaluated.Here is a less obvious but still poor example of using a value-returning statement. In our Math Tutor project, a student might have a statement like this:
numCorrect = numCorrect + checkAnswer(....);
This could work correctly if the student made
checkAnswer a value-returning function which returned 1 if the answer was correct and 0 if the answer was incorrect. The problem is, code is clearest if it reads as much like an algorithm as possible. It doesn't make sense to add "checkanswer" to something. The term "check answer" is an instruction, not a quantity. It would be clearer to make checkAnswer a void function and saycheckAnswer(.....,numCorrect);
and let the checkAnswer function update numCorrect. The code above (where
checkAnswer was a value-returning function) violates the AND NOTHING ELSE part of our when-to-use-value-returning-functions rule. previous section | next section
Created by David Harden.
Please do not print or copy except for a single copy
for students taking CIS10A at Santa Rosa Junior College