Notes on Teaching Programming quite possibly from a 'STEM' perspective. This is a course designed for upper school or high school students at Saint Paul's Academy in Bellingham, WA. An associated web page is http://teachingprogramming.rmfmedia.com/ .

Thursday, November 21, 2013

K&R C SE Lesson 2: Introducing printf, the 'for loop', and gdb

(Post Under Construction)This post uses an example from the first chapter of K&R C Programming Second Edition. After discussing the use of the printf function, K&R C SE demonstrates alternate code for printing a Fahrenheit-Celsius conversion table. The specific and compact use of printf arguments allows for the appropriate formatting of the results returned by a compact conversion routine inside of a for loop. This code is more compact and more accurate than the first example in Lesson 1 using the while loop:#include <stdio.h>/* print Fahrenheit-Celsius table */main(){int fahr;for (fahr = 0; fahr <= 300; fahr = fahr + 20) printf("%3d %6.1f\n", fahr, (5.0/9.0) * (fahr-32));}

You can compile the code above (after creating the text file "FAHRfor.c") with gcc as below on Cygwin X11 terminal.On a MAC you will not need to append '.exe' to your compiled executable file name. The option '-o' specifies the output binary or compiled file name.

gcc FAHRfor.c -o FAHRfor.exe

Running the binary on Cygwin produces the conversion table:

./FAHRfor.exe

0 -17.8

20 -6.7

40 4.4

60 15.6

80 26.7

100 37.8

120 48.9

140 60.0

160 71.1

180 82.2

200 93.3

220 104.4

240 115.6

260 126.7

280 137.8

300 148.9

gcc has many options. Use 'man gcc' or 'info gcc' for more information. The option '-g' creates code with symbols useful for debugging.

gcc -g FAHRfor.c -o FAHRfor.exe

gdb or gnudbg allows the user to 'step' through code compiled with '-g' option. You start it by suffixing the binary or compiled file name to gdb. At the gdb prompt we will set a 'breakpoint' for each line in the source code. Next we will 'run' the code (inside of gdb) and then 'step' through the execution of each conversion in the for loop. I have marked in bold the debug output results of the first two lines of conversion.

gdb FAHRfor.exe

...

Reading symbols from /home/rferrisx/FAHRfor.exe...done.

(gdb) break 1

Breakpoint 1 at 0x40117e: file FAHRfor.c, line 1.

(gdb) break 2

Note: breakpoint 1 also set at pc 0x40117e.

Breakpoint 2 at 0x40117e: file FAHRfor.c, line 2.

(gdb) run

Starting program: /home/rferrisx/FAHRfor.exe

[New Thread 10972.0x3618]

[New Thread 10972.0x14a4]

Breakpoint 1, main () at FAHRfor.c:6

6 for (fahr = 0; fahr <= 300; fahr = fahr + 20)

(gdb) s

7 printf("%3d %6.1f\n", fahr, (5.0/9.0) * (fahr-32));

(gdb) s

0 -17.8

6 for (fahr = 0; fahr <= 300; fahr = fahr + 20)

(gdb) s

7 printf("%3d %6.1f\n", fahr, (5.0/9.0) * (fahr-32));

(gdb) s

20 -6.7

....

Debugging is an essential skill for programming and debuggers have extensive functionality. Instrumented code can allow the programmer to output debug messages. However, most code can be debugged by producing a debug version of the source as we have demonstrated here.