Here are a tracing problem and some random number
problems to give you some practice.
The comments have purposely been omitted from
the trace code.
After performing the problems click the problem or
problem name to see the answer.
Explanations are also given for each of the problems.
The next line a = F(b);
Execution of the program now leaves main()
and enters the function F().
where the variables b and
c have been declared,
but still contain garbage, indicated by ~ .
The next line of code, c = G(b); is a call to
the function G() passing the value of
b , which is 5.
Execution of the program now leaves F()
and enters the function G()
where the variables a and
c have been declared,
but still contain garbage, indicated by ~ .
The next statement a = c - 2;is executed.
The next statement,
printf("G: a = %d, b = %d, c = %d\n", a, b, c);
is executed.
When the next statement, return a; gets
executed, the value of G()'s a, 10, gets
returned back to the calling function, F().
The program execution now leaves the function G()
and returns to the calling function, F().
Where does the execution pick up in F() and what
happens to the value being returned, 10 ?
The next statement,
printf("F: a = %d, b = %d, c = %d\n", a, b, c);
is executed.
When the next statement, return c; gets
executed, the value of F()'s c, 10, gets
returned back to the calling function, main().
The program execution now leaves the function F()
and returns to the calling function, main().
The execution begins on the same line that called F()
, a = F(b); and the value being returned,
10, replaces the call (the part of the statement on the right-hand side
of the assignment operator). Basically, you can think of the statement
as looking like this: a = 10;
So the value 10 gets assigned into main()'s a
yielding:
The next line c = G(a);
Execution of the program now leaves main()
and enters the function G().
where the variables a and
c have been declared,
but still contain garbage, indicated by ~ .
The next statement a = c - 2; is executed.
The next statement,
printf("G: a = %d, b = %d, c = %d\n", a, b, c);
is executed, yielding :
When the next statement, return a; gets
executed, the value of G()'s a, 15, gets
returned back to the calling function, main().
The program execution now leaves the function G()
and returns to the calling function, main().
The execution begins on the same line that called G()
, c = G(a); and the value being returned,
15, replaces the call (the part of the statement on the right-hand side
of the assignment operator). Basically, you can think of the statement
as looking like this: c = 15;
So the value 15 gets assigned into main()'s c
yielding:
The next statement,
printf("main: a = %d, b = %d, c = %d\n", a, b, c);
is executed.
Finally, the return 0; statement in
main() is reached.
Explanation 1
For this explanation the color blue will be associated with main(),
red with the function F(),
and green with the function G().
The line: int a, b, c;
in main() declares three integer variables known only to main() called
a, b, and
c.
On the next line a = b = c = 0;
all of those variables are assigned the value 0.
Since the associativity of the assignment operator is from right to left,
first c gets assigned the value 0,
then b gets assigned the value of
c, which is 0.
Finally a gets assigned the value of
b, which is 0.
Which yields:
is a function
call to the function F()
The value of the variable b gets passed to
the function.
So the value 0 gets passed to F()
Which yields:
When we examine the function header for the function F()
, we see int F (int a).
We find that the value passed into the function will be stored in
F()'s only parameter,
an integer variable called a.
Within the function F() , there are two
other local variables declared, int b, c;
So F() actually has three local variables,
a , b , and
c , known only to this function,
F() .
The memory locations for these variables are different from the locations
of main()'s a, b, and c.
After the function F()'s declarations, we have:
The next line executed within the function F()
is b = 2 * a + 5;.
Substituting 0, the value of a into the
expression, we get 2 * 0 + 5;
multiplying first, we get 0 + 5 = 5.
So the value 5 gets assigned into b yielding :
Which yields:
When we examine the function header for the function
G(), we see int G (int b)
.
We find that the value passed into the function will be stored in
G()'s only parameter,
an integer variable called b.
Within the function G() , there are two
other local variables declared, int a, c;
So G() actually has three local variables,
a , b , and
c , known only to this function,
G() .
The memory locations for these variables are different from the locations
of F()'s a, b, and c
and
main()'s a, b, and c.
After the function G()'s declarations, we have:
The next statement c = b + 7; is executed.
Substituting the value of b , 5, into the
expression, we get c = 5 + 7;
So c gets assigned the value 12. Yielding:
Substituting the value of c , 12, into the
expression, we get a = 12 - 2;
So a gets assigned the value 10. Yielding:
This is the first statement of the program that produces output. The value
of G()'s variable a
gets printed in the position of the first %d in the string of the printf
statement, since it is in the first position in the list of variables to be
printed. Similarly, the value of G()'s variable
b gets printed in the position of the second
%d and c gets printed in the position of the
last %d.
So the letter G: and the values of G()'s
variables a, b, and c get printed to the
screen as shown in the output box below.
All of G()'s variables go out of scope, yielding:
The execution begins on the same line that called G()
, c = G(b); and the value being returned,
10, replaces the call (the part of the statement on the right-hand side
of the assignment operator). Basically, you can think of the statement
as looking like this: c = 10;
So the value 10 gets assigned into F()'s c
yielding:
This is the second statement of the program to produce output.
So the letter F: and the values of F()'s
variables a, b, and c get printed to the
screen as shown in the output box below.
All of F()'s variables go out of scope, yielding:
is a function
call to the function G()
The value of the variable a gets passed to
the function.
So the value 10 gets passed to G()
Which yields:
When we examine the function header for the function
G(), we see int G (int b).
We find that the value passed into the function will be stored in
G()'s only parameter,
an integer variable called b.
Within the function G() , there are two
other local variables declared, int a, c;
So G() actually has three local variables,
a , b , and
c , known only to this function,
G() .
The memory locations for these variables are different from the locations
of main()'s a, b, and c.
After the function G()'s declarations,
we have:
The next statement c = b + 7; is executed.
Substituting the value of b , 10, into the
expression, we get c = 10 + 7;
So c gets assigned the value 17. Yielding:
Substituting the value of c , 17, into the
expression, we get a = 17 - 2;
So a gets assigned the value 15. Yielding:
All of G()'s variables go out of scope, yielding:
The value 0 is returned
back to the operating system, indicating to the operating system that
the program ran normally to completion.
Explanation 2
The function definitions for the functions srand() and rand() are
both found in the stdlib library
and their function prototypes are found in the associated header file called
stdlib.h.
So in order to be able to call the functions from your program without
warnings and possible errors,
you must #include <stdlib.h> so the prototypes can be seen before
the calls to those functions.
Explanation 3
The function srand() seeds the random number generator with the value
passed in. Since the call in this case is srand(10);, the value 10 is
used as the seed. That means that the calculations that will produce the
first pseudo-random number will use a beginning value of 10.
You can think of a call to srand() as turning on the random number
generator. No random numbers are produced until there is a call to
rand().