Walkthroughs that involve functions are more involved and require a modification on how we track our data. Namely we need to not only track the variables but also our stack frames. This example explains how to do this:
How to do Walkthroughs With Functions
What is the output of the following program?
#include <stdio.h>
int strawberry(int leaves);
int pies(int crusts);
int main(void)
{
int apple = 3;
int orange = 12;
apple += strawberry(orange);
printf("apple: %d\n", apple);
apple += pies(7);
printf("apple: %d\n", apple);
return 0;
}
int strawberry(int leaves)
{
int rc = leaves*2;
rc += 5;
printf("strawberry rc = %d\n", rc);
return rc;
}
int pies(int crusts)
{
int rc = crusts;
rc += strawberry(crusts % 5 + 2);
printf("pies rc = %d\n", rc);
return rc;
}
- Video of how to do this walkthrough can be found here: https://youtu.be/6AyqeHRNLBE
- Written summary below:
Step 1:
As always we start in main by creating a table for the variables in main But... we also identify below the table that the variables exist within the main function
After completing:
int apple = 3;
int orange = 12;
We get:
Next, line of code requires we call the function strawberry() before we can add the return value from it to apple.
apple += strawberry(orange);
We indicate this in our rough work by drawing a vertical line beside our main table and writing down the name of the next function that we call. We create a new table in the strawberry() section to track the variables and parameters of strawberry(). In this case rc and leaves. leaves is passed from the main function to strawberry() so its initial value is whatever was passed in (the value of orange in this case) and rc is initialized to leaves * 2
To help us remember what line we the function call was made, we also add a circle with a line number of where the function call was made from and an arrow that points to the function we called.
Next we have:
int rc = leaves*2;
rc += 5;
printf("strawberry rc = %d\n", rc);
return rc;
We follow the code and update our variables as need
Our output at this point:
strawberry rc = 29
Our next line:
return rc;
This is our return statement. As soon as we get here we go back to calling function. Our function ends and any variables/parameters in our function are destroyed. We can indicate this by putting a big X through it and an arrow back to main to indicate that the function is completed. The value that is returned (29) essentially replaces the function call.
apple += strawberry(orange);
can be viewed as apple += 29
because 29 is the return value from the function call:
Next we have a print statement:
printf("apple: %d\n", apple);
Our full output is now:
strawberry rc = 29
apple: 32
The next line sees another function call
apple += pies(7);
Once again, we indicate that we are calling the pies() function by adding "pies()" to the right of the vertical line and put together a table for pies() variables and parameters. 7 is passed to the function, thus crusts is 7 initially. rc is initialized with crusts so rc is also 7
int pies(int crusts)
{
int rc = crusts;
Next we have a function call:
rc += strawberry(crusts % 5 + 2);
This is a function call to strawberry() using an expression as the argument. Before we call the function we must first work out what the expression crusts % 5 + 2 evaluates to:
crusts % 5 + 2
7 % 5 + 2
2 + 2
4
Thus, we are passing 4 into the strawberry() function
This:
rc += strawberry(crusts % 5 + 2);
is effectively this:
rc += strawberry(4)
We indicate this in our rough work by drawing a vertical line to the right of the pies() table and create a table for strawberry(). We indicate what line we called strawberry() from using a circled line number from pies(). We initialize rc and leaves in the strawberry() function based on the value passed to the function
Next we follow the code, printing as needed
rc += 5;
printf("strawberry rc = %d\n", rc);
Our output is now:
strawberry rc = 29
apple: 32
strawberry rc = 13
At this point we are hitting the return statement
return rc;
We follow the arrow back from strawberry() to the calling function pies() at the indicated line and provide the return value (13 in this case as that is the value of rc). We also indicate that the strawberry() function is completed by crossing out the table.
This return value takes the place of the function call and we calculate an update to the rc that is in pies() function:
rc += strawberry(crusts % 5 + 2);
is
rc += 13
Now we do the printf() statement:
printf("pies rc = %d\n", rc);
Thus our output is now:
strawberry rc = 29
apple: 32
strawberry rc = 13
pies rc = 20
Next we hit our return statement in pies()
return rc;
And thus, we will return the number 20 to the calling function of pies(), which is main()
apple += pies(7);
We indicate this by crossing out the pies() table and drawing an arrow back to main() at line 12.
At this point our function call:
apple += pies(7);
is effectively:
apples += 20
We update our table one last time and do the printf() call.
Our final output is:
strawberry rc = 29
apple: 32
strawberry rc = 13
pies rc = 20
apple: 52