Debugging Simple Programs: CISC 181 Lab 2, Lab Reports of Computer Science

A lab guide for students in cisc 181 to learn effective methods for finding and eliminating errors, or bugs, in c++ programs. It includes instructions for setting up the lab environment, the concept of the editing-compiling-debugging loop, and guidelines for debugging. The document also provides a copy of a program that takes a binary number as input and prints the equivalent decimal number, and suggests adding debugging statements to help identify errors.

Typology: Lab Reports

Pre 2010

Uploaded on 09/02/2009

koofers-user-m5u
koofers-user-m5u 🇺🇸

4

(1)

9 documents

1 / 6

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
CISC 181 Lab 2
Debugging Simple Programs
Week of September 15, 2003
“There are two ways to write error-free programs; only the third one works.”
“To understand a program you must become both the machine and the program.”
Alan J. Perlis
Remember that the primary objective in lab is to learn. Read the lab instructions carefully and ask questions
of the TA1or a classmate if there are things that you do not understand. You are encouraged to work together
during the labs for more efficient learning. Try to help each other learn as much as possible. Enjoy!
Today’s Lab
The objective of today’s lab is to teach (or remind) you some simple, but effective, methods for finding and
eliminating “bugs” in programs. This is usually the most time consuming part of programming. You may
not be able to finish the entire lab in 50 minutes. Do not worry, just work at a steady pace, and make sure
that you understand each step. At the end of the lab, hand-in what you have completed. If you wish to
complete the lab later, you are encouraged to do so! It will help you to learn even more things that will help
you work more effectively on programming tasks that we will be doing all semester long.
Making Sure You Have the CISC 181 Computing Environment
Be sure that you have done the command
strauss> newgrp 200x
where
x is 3 for the Thursday labs, 2 for the Wed labs, and 5 for the Mon labs. Also, see the course homepage for
these project numbers.
After doing the above, you should see the prompt CIS181> on your screen. If not, redo the command
strauss> ~caviness/Class/CISC1810xx/student-setup
where xx is 80 for the Monday labs, 13 for the Wed labs, and 10 for the Thur labs.
Now retry the newgrp command and make sure you get the CIS181>prompt.
Remember if you wish to leave the CISC 181 environment after you complete work, you must type
CIS181> exit
This must be done before you can go through the normal “logout” sequence that you would do if you were
not using an X-terminal, for example, when you are working from home or your dorm room.
The Editing-Compiling-Debugging Loop
When working on a C++ program it is convenient to use two windows—one for editing the program file
and a second for doing compilations, executions of the compiled program, and reading error messages. This
way, you can go back and forth quickly between editing the file and compiling it. Also you can look at
the compiler produced error messages in one window and your file containing the C++ code in the other.
Clearly this speeds-up debugging.
1Staci Lyvers is the TA for the Monday labs, Brad Durandetta for the Wed labs, and Greg Waltz for the Thur labs.
1
pf3
pf4
pf5

Partial preview of the text

Download Debugging Simple Programs: CISC 181 Lab 2 and more Lab Reports Computer Science in PDF only on Docsity!

CISC 181 Lab 2

Debugging Simple Programs

Week of September 15, 2003 “There are two ways to write error-free programs; only the third one works.” “To understand a program you must become both the machine and the program.” Alan J. Perlis

Remember that the primary objective in lab is to learn. Read the lab instructions carefully and ask questions of the TA^1 or a classmate if there are things that you do not understand. You are encouraged to work together during the labs for more efficient learning. Try to help each other learn as much as possible. Enjoy!

Today’s Lab

The objective of today’s lab is to teach (or remind) you some simple, but effective, methods for finding and eliminating “bugs” in programs. This is usually the most time consuming part of programming. You may not be able to finish the entire lab in 50 minutes. Do not worry, just work at a steady pace, and make sure that you understand each step. At the end of the lab, hand-in what you have completed. If you wish to complete the lab later, you are encouraged to do so! It will help you to learn even more things that will help you work more effectively on programming tasks that we will be doing all semester long.

Making Sure You Have the CISC 181 Computing Environment

Be sure that you have done the command

strauss> newgrp 200x

where x is 3 for the Thursday labs, 2 for the Wed labs, and 5 for the Mon labs. Also, see the course homepage for these project numbers.

After doing the above, you should see the prompt CIS181> on your screen. If not, redo the command

strauss> ~caviness/Class/CISC1810xx/student-setup

where xx is 80 for the Monday labs, 13 for the Wed labs, and 10 for the Thur labs.

Now retry the newgrp command and make sure you get the CIS181> prompt.

Remember if you wish to leave the CISC 181 environment after you complete work, you must type

CIS181> exit

This must be done before you can go through the normal “logout” sequence that you would do if you were not using an X-terminal, for example, when you are working from home or your dorm room.

The Editing-Compiling-Debugging Loop

When working on a C++ program it is convenient to use two windows—one for editing the program file and a second for doing compilations, executions of the compiled program, and reading error messages. This way, you can go back and forth quickly between editing the file and compiling it. Also you can look at the compiler produced error messages in one window and your file containing the C++ code in the other. Clearly this speeds-up debugging. (^1) Staci Lyvers is the TA for the Monday labs, Brad Durandetta for the Wed labs, and Greg Waltz for the Thur labs.

WARNING: DO NOT EDIT THE SAME FILE IN TWO WINDOWS SIMULTANEOUSLY.

Only the changes made in the most recent SAVED file will be kept. So if you make changes in one window, and later save the file in the other window, the changes saved in the first window are written over and DESTROYED by the second save.

Errors (or bugs) are either syntactical or logical. Syntax errors are reported by the compiler during compi- lation. On the other hand, logical errors are not reported by the compiler. If you execute a file with logical errors, it will produce incorrect results or terminate with a run-time error. Examples of some common logical errors are:

  1. Improper or no initialization of variables.
  2. Inadvertently inserting null statements in “if” and looping statements. For example,

if (a == b) ;

while (n <= 5) ;

  1. Improper processing of loop control variables (counters or others).
  2. Confusing == and =.
  3. Infinite loops due to items 2,3 or due to improper check conditions at the entry point of the loop structures.
  4. Unnecessarily complicated program structures.

There are a number of ways to debug a program. Use of a windows debugger which is a part of an integrated programming environment called workshop may be taught in later labs^2. Let us now learn a simple, but effective, way to debug a program, that is, by putting extra print statements, called debugging statements, at various places in your program as checkpoints. These will normally be removed before turning in the program for grading (or before delivering the software to customers, who are the ones who do the grading in the real world).

Some guidelines for debugging

Know how to do the algorithm by hand You have to completely understand the method (algorithm) to be programmed before you can write a program or debug an existing, non-working program. Making sure that you can do examples by hand before working on the program.

Attitude adjustment needed As the authors of programs, we are naturally chagrined when we find an error in one of our carefully crafted programs. But when we switch from the role of writing a program to debugging it, we want to ruthlessly search for errors and be happy when we find (and correct) them! After all, it is much better for us to find our own errors than for the grader to find them or, even worse, for our customers to find them when we are working for a software company. Because authors of programs are often blind to their own errors, commercial software companies usually have different persons test programs after the program writers have done the best they can.

Choosing test data One of the most important aspects of debugging is the choice of data on which to run tests. Some rules of thumb for choosing test data sets are:

Begin simply Choose the simplest possible data sets on which to initially test a program. Then progress to more complicated data. Beginning programmers often make the mistake of testing their programs on data that is much too complicated. (^2) workshop is a petty cool program that is similar to the Microsoft visual environment. If you would like to try it, type /opt/bin/workshop at the Unix prompt and then click on one of the help or demo buttons to learn about workshop. You must have eXceed installed to use workshop on your home machine to see the windows created by this X-windows application.

for (int i = 2; i <= n; i++){ ans *= i }

return ans; }

Use endl instead of \n for new lines to insure that the time of output is synchronized with the execution of the program instead of being delayed until an internal buffer is filled.

A Debugging Exercise

  1. Copy the following program from the class account by typing the command:

CIS181> cp $CLASSHOME/labs/lab02/program.cc

Below is a copy of the program. It contains both syntactical and logical errors. You are required to remove both kinds of bugs from the program and turn in a correct version of it along with the compilation and execution steps. The program takes as input a binary number and prints the equivalent decimal number. You input the binary number by typing a decimal number consisting only of 0s and 1s. The program is based on the following table. Make sure that you understand the table.

1(base 2) = 1(base 10) 10(base 2) = 2(base 10) 100(base 2) = 4(base 10) 1000(base 2) = 8(base 10) 10000(base 2) = 16(base 10)

Hence 10010(base 2) = 16 + 2 = 18(base 10). If the program reads the number 10010, it should print the decimal equivalent of the binary number 10010 which is 18. The program uses a right-to-left conversion method that will be described by the TA.

  1. Think about how you would write a program for this problem. By hand convert some binary numbers to decimal. For example, what are the decimal equivalents of the binary numbers 101, 111, 1101? Now look at the program and try to figure out how it INTENDS to do the job. Note that there are bugs in the program that you have to fix. If you have no idea what the program is trying to do, ask the TA or a classmate for help.
  2. Before making any changes, try to compile the program using CC. Follow the line numbers printed to trace the syntactical errors in the program.
  3. At this point open a second window.
  4. In the second window, display the copied file using an editor, xemacs or one of the versions of vi, vi or gvim. In the first window, use CC to compile the program and read the error messages. Now make corrections to the program in the second window. BE SURE TO WRITE OUT (SAVE) THE FILE AFTER MAKING THE CORRECTIONS.
  5. Then compile again in the first window. The Unix command !C will be useful here to repeat the most recent command beginning with C, presumably your CC command to compile the program. If you do not remember this from lecture ask the TA or a classmate how to use it.

// The following program takes as input a binary number // and prints the equivalent decimal number. You input the // binary number by typing a decimal number consisting only of 0s and 1s. // The program is based on the following table:

// 1(base 2) = 1(base 10) // 10(base 2) = 2(base 10) // 100(base 2) = 4(base 10) // 1000(base 2) = 8(base 10) // 10000(base 2) = 16(base 10)

// Hence 10010(base 2) = 16 + 2 = 18(base 10).

// If the program reads the number 10010, it should print // The decimal equivalent of the binary number 10010 is 18.

#include using namespace std;

main() { int binaryNum;

cout << "Enter a binary number consisting of 0s and 1s only: "; cin >> BinaryNum;

int b = binaryNum, // b will be loop control variable. powerOf2 = 1; // Initialize to 2^0. decimalEquiv = 0;

while (b != 0) { if (b%10 = 1) // Check lower order "bit" of b decimalEquiv = decimalEquiv * powerOf2; powerOf2 = 2-powerOf@; // Compute next power of 2. b = b/10; // Lop off right-most (low-order) "bit" }

cout << "The decimal equivalent of the binary number " << binaryNum << " is " decimalEquiv << endl; return 0; } //--------------------------------------------------------------------

  1. Below is a copy of the program that illustrates one way to put in the extra print statements (called TRACERS) to help debug the program. You can get a copy of this for your own use by typing the command:

cp $CLASSHOME/labs/lab02/tracer.cc

#include using namespace std;

main() { int binaryNum;

cout << "Enter a binary number consisting of 0s and 1s only: "; cin >> BinaryNum;