The First Easy Application
The I/O tools provided can make programming much easier, more readable, and cleaner. However, there are times that a programmer just needs to see how the program in development is working.
The printf function is a handy tool for conducting debugging operations and some examples are provided in this section. Note that some of the examples are beyond the current learning sequence at this point but the fundamentals of debugging with a printf function are all the same, and students can always come back to this section to get ideas on how to use this in the later parts of this reference.
Easy Start
The simplest example is for a programmer to want to verify input to a program, shown here.
printf( "Enter your birth year: " );
scanf( "%d", &intInput );
printf( "year entered: %d\n", birthYear )
In a simple program, this is really not necessary but if the program conducts many more complicated operations after the input, it may be a good idea to make sure the program got the input the programmer meant for it to.
In important thing to consider here, and with all diagnostic printing is to make sure the \n is placed in the printf statement. Placing this in the printed string part normally ends the line anyway. However, if a program is acting poorly and possibly crashing, and the \n is not placed in the string, it is unlikely to get printed before the crash and the programmer won't get the information needed to diagnose the condition. Programmers will almost always place a \n in the printf string when conducting diagnostic operations. Examples of the few times this is not done will be provided later in this section.
Function Calls
Another relatively easy way to use the printf function is in the main function which is commonly used as a driver for calling other functions. Consider the following code.
age = getAge();
height = getHeight();
weight = getWeight();
displayPersonInfo( age, height, weight )
This jumps right into thinking and being strategic about your diagnostics. With consideration for this code, think about where a printf statement might be placed if the age and the weight are printed correctly but the height is either zero or some unusual number (technical term: garbage).
It should be obvious that the programmer would diagnostically print the height value immediately after the call to getHeight. And that is shown here.
age = getAge();
height = getHeight();
height = printf( "input height: %d\n", height );
weight = getWeight();
displayPersonInfo( age, height, weight )
The expectation is that the number will be incorrect right at this point since it is not modified anywhere later on, but this is a systematic verification of the data before moving to the next step, which would be to look inside the function, as shown here.
int getHeight()
{
int inputVariable;
// place diagnostic print statement here BEFORE code operations
printf( "inside getHeight, initialized variable: %d\n",
inputVariable );
// prompt user for input, etc.
.
.
.
.
// place diagnostic print statement here AFTER code operations
printf( "inside getHeight, acquired variable: %d\n",
inputVariable );
Decision Making
Again, there should be no surprise here. Consider the following code.
printf( "before if test, someValue: %d\n", someValue );
if( someValue < someOtherValue )
{
// printf( "after if test, someValue: %d\n", someValue );
// next code
The key is to place the printf statement where it provides information about what decision was made, or not made. Further diagnosing can continue from there as needed.
Iterating (Looping)
Sometimes the data in a loop just doesn't do what the programmer wanted it to do, and/or it is doing something that doesn't make sense. There are a couple of ways to address this. The first way is to print out what the loop is doing by starting a new line after every print statement, as shown here.
while( someValue < someMax )
{
// printf( "someValue: %d\n", someValue );
// next code
However, this strategy will obviously fill the screen pretty quickly. The strategic diagnostician could print the data out in such a way that it comes out horizontally and potentially easier to understand. This strategy is not very different from the other and is provided here.
while( someValue < someMax )
{
// printf( "someValue: %d, ", someValue );
// next code
}
printf( "\n" );
In this case, the printf inside the loop does not have a \n in the string but it does have a comma and a space. To make this work and not inappropriately displace the next displayed outputs, this strategy should include placing a printf with a \n after the end of the loop.
Simple Debugging
Again, be aware that there are parts of this section with which students may not have interacted yet. Not a problem because they can use what they are familiar with, and more importantly come back later after having learned the more advanced operations, and apply these strategies.
To be clear, using the printf statement is only part of debugging. Programmers must use their best logical and diagnostic thinking to know where to place those functions. While it is true that printf statements can be scattered all over the place, it won't help unless it provides what is called "actionable information" in industry. If the printf provides information that leads to identifying the issue, then it is being used correctly.