cs1ch4sec5.htm
 

Chapter 4
 
Design with Functions


Section V: Tracing Section I: Decomposition Section II: Functions Section III: Output, Calculation, and Display Functions
Section IV: Parameters Section VI: Final Thoughts on Redesigning the Employee Salary Problem

  


Table of Contents

Learning C++:
An Index of Entry Points


2. The

of C++

A reference document on the basic elements of C++.



3. The Patterns



Index!



Section V. Tracing
As we have already seen, tracing is also a valuable tool for understanding how code works. Let's trace the code found in ch4prg2.cpp.

Step 1: Create a column for each variable involved. (Since the constant, NUM_TIMES, never changes, we will ignore it in our trace.) This step is a bit more complex in a program involving functions. When the program begins only the variables and constants known in 'main' have memory associated with them. The formal parameters and other local variables of the other functions do not yet have memory associated with them. Therefore, the trace starts as follows:

rateOfPay salary hoursWorked count
? ? ? 0

These variables all come from 'main'. Only the variable 'count' is initialized (to 0) when it is declared so only it is initialized in the trace to a specific value. The rest are initialized in the trace to garbage via the '?' symbol.

Step 2: As with other programs involving user input, we need to create the data to be entered. How about:

Rate of Pay Hours Worked   
Employee1    10.00 20
Employee2 5.00 10
Employee3 20.00 40

Notice that we have chosen data that is easy to work with. Also, since we are not concerned here with testing the overtime calculations and those calculations are more complex, we have avoided using data that would require such. Finally, although the loop will continue NUM_TIMES, we need only check the first few employees to learn how this code functions. The moral: always use data that thoroughly tests what you want to test but does so as simply as possible.

Step 3: Walk through the code.

We start at the top of the 'for' loop and compare 'count' to NUM_TIMES, the constant set to 10 in our code. Since 'count' is less than NUM_TIMES we proceed into the loop and call 'GetEmployeeInformation'. When this call is made, the two parameters, 'rate' and 'hours', appear in the trace because each now has memory associated with it. Notice that 'rate' and 'hours' are placed in the same columns as 'rateOfPay' and 'hoursWorked' respectively since they are symbolic nicknames for the same memory locations.

rateOfPay salary hoursWorked count
alias: rate alias: hours
? ? ? 0

At this point 'rateOfPay' has garbage and therefore so does 'rate'. Same for 'hoursWorked' and 'hours'.

'GetEmployeeInformation' calls 'GetRateOfPay' and now a new variable appears in the trace - the local variable (local to 'GetRateOfPay') 'payRate'.

rateOfPay salary hoursWorked count payRate
alias: rate alias: hours
? ? ? 0 ?

'GetRateOfPay' asks the user to enter the first employee's rate of pay. The value 10.00 is entered and is stored in 'payRate'

rateOfPay salary hoursWorked count payRate
alias: rate alias: hours
? ? ? 0 10

Note that at this point the 10.00 is only in 'payRate'. However, as soon as the 'return' instruction is executed in 'GetRateOfPay' and 10.00 is returned to 'GetEmployeeInformation', this value is stored in ''rate' which, of course, means that the same value is also in 'rateOfPay'. The same happens with 'hours'/'hoursWorked' and the trace is shown below. (Note that the variable 'payRate' has disappeared - with the completion of 'GetRateOfPay'.)

rateOfPay salary hoursWorked count
alias: rate alias: hours
10.00 ? 20 0

Continuing through the code, 'GetEmployeeInformation' is completed and the code returns to the next line in 'main'. With the completion of 'GetEmployeeInformation' the aliases for 'rateOfPay' and 'hoursWorked' both disappear. However, the values placed in them remain as the values of 'rateOfPay' and 'hoursWorked'.

rateOfPay salary hoursWorked count
10.00 ? 20 0

The next line in 'main' is a call to 'CalculateSalary'. We won't bother to show the trace of what happens inside this function but it should be clear that the system concludes that 20 is less than REGULAR_HOURS and therefore it jumps to the code in the 'else' part of the 'if'. The full salary is therefore calculated as being 200.00 (10.00 * 20) and this value is returned whereupon it is assigned to the variable 'salary'. This value is then output via the 'OutputSalary' function and the system reaches the bottom of the loop where 'count' is incremented by 1 and the trace looks as follows:

rateOfPay salary hoursWorked count
10.00 200.00 20 1

Output: 200.00

Now the system goes to the top of the loop, again compares 'count' with NUM_TIMES, determines that 'count' is less than NUM_TIMES, and enters into the loop for the second time. 'GetEmployeeInformation' is again called and this time 'rateOfPay' (alias 'rate) has 10.00 while 'hoursWorked' (alias 'hours') has 20 as its value. These values are immediately lost, as before, when 'GetRateOfPay' and 'GetHoursWorked' are called. The user enters 5.00 for the rate of pay and 10 for the hours worked. The result, for the trace, just before 'GetEmployeeInformation' completes, is as follows:

rateOfPay salary hoursWorked count
alias: rate alias: hours
10.00 200 20 1
5.00 10

Continuing with this trace is an exercise you might want to try. Hopefully, however, you see how the call to 'GetEmployeeInformation' works. More generally, hopefully, you see what happens when a function with parameters is called and how to have a function return more than one value.

Beyond these two points there is something else to observe related to the whole issue of functional decomposition. With a trace involving functions, it is possible to focus on certain code while ignoring other code. In the trace we just completed we focused on 'main' and 'GetEmployeeInformation' and just assumed that the other functions executed correctly. In other words, since we were not interested in how these other functions did what they did we simply recorded what they did.

Of course, if we were tracing this code because we were getting incorrect results and we suspected that the problem was in 'CalculateSalary', we would focus on it and not, perhaps, on 'GetEmployeeInformation'. They key point is that we can focus on whatever part of a program seems important at the time and ignore the rest.

Top of Section Main Menu Next Section