Programming Hints :
Programming Hints :
It is not our purpose in this book to teach you how to program, only how to program
better. We assume you are familiar with such fundamental concepts as variables,
conditional statements (e.g., if-then-else, case), iteration primitives (e.g., for-do,
while-do, repeat-until), subroutines, and functions. If you are unfamiliar with these
concepts you may have picked up the wrong book, but buy it anyway for later use.
It is important to realize how much power there is in what you already know. In
principle, every interesting algorithm/program can be built from what you learn in a
first programming course. The powerful features of modern programming languages are
not really necessary to build interesting things – only to do them in cleaner, better
ways.
To put it another way, one becomes a good writer not by learning additional vocabulary
words but by finding something to say. After one or two programming courses,
you know all the words you need to make yourself understood. The problems in this
book strive to give you something interesting to say.
We offer a few low-level coding hints that are helpful in building quality programs.
The bad examples all come from actual submissions to the robot judge.
• Write the Comments First — Start your programs and procedures by writing a
few sentences explaining what they are supposed to do. This is important because
if you can’t easily write these comments, you probably don’t really understand
what the program does. We find it much easier to debug our comments than our
programs, and believe the additional typing is time very well spent. Of course,
with the time pressure of a contest comes a tendency to get sloppy, but do so at
your own risk.
• Document Each Variable — Write a one-line comment for each variable when
you declare it so you know what it does. Again, if you can’t describe it easily, you
don’t know why it is there. You will likely be living with the program for at least
a few debug cycles, and this is a modest investment in readability which you will
come to appreciate.
• Use Symbolic Constants— Whenever you have a constant in your program (input
size, mathematical constant, data structure size, etc.) declare it to be so at the
top of your program. Horribly insidious errors can result from using inconsistent
constants in a program. Of course, the symbolic name helps only if you actually
use it in your program whenever you need the constant. . .
• Use Enumerated Types for a Reason— Enumerated types (i.e., symbolic variables
such Booleans (true,false)) can be terrific aids to understanding. However, they
are often unnecessary in short programs. Note this example representing the suit
(club, diamond, heart, spade) of a deck of cards:
switch(cursuit) {
case ’C’:
newcard.suit = C;
break;
case ’D’:
newcard.suit = D;
break;
case ’H’:
newcard.suit = H;
break;
case ’S’:
newcard.suit = S;
...
No additional clarity arises from using the enumerated variables (C,D,H,S)
over the original character representation (’C’,’D’,’H’,’S’), only additional
opportunities for error.
• Use Subroutines To Avoid Redundant Code — Read the following program fragment
managing the state of a rectangular board, and think how you might shorten
and simplify it:
...
while (c != ’0’) {
scanf("%c", &c);
if (c == ’A’) {
if (row-1 >= 0) {
temp = b[row-1][col];
b[row-1][col] = ’ ’;
b[row][col] = temp;
row = row-1;
}
}
else if (c == ’B’) {
if (row+1 <= BOARDSIZE-1) {
temp = b[row+1][col];
b[row+1][col] = ’ ’;
b[row][col] = temp;
row = row+1;
}
}
...
In the full program, there were four blocks of three lines each moving a value to a
neighboring cell. Mistyping a single + or − would have lethal consequences. Much
safer would be to write a single move-swap routine and call it with the proper
arguments.
Make Your Debugging Statements Meaningful — Learn to use the debugging
environment on your system. This will enable you to stop execution at a given
statement or condition, so you can see what the values of all associated variables
are. This is usually faster and easier than typing in a bunch of print statements.
But if you are going to insert debugging print statements, make them say something.
Print out all relevant variables, and label the printed quantity with the
variable name. Otherwise it is easy to get lost in your own debugging output.
Most computer science students are now well-versed in object-oriented programming,
a software engineering philosophy designed to construct reusable software components
and exploit them. Object-oriented programming is useful to build large, reusable programs.
However, most of the programming challenge problems in this book are designed
to be solved by short, clever programs. The basic assumption of object-oriented programming
just does not apply in this domain, so defining complicated new objects (as
opposed to using predefined objects) is likely to be a waste of time.
The trick to successful programming is not abandoning style, but using one
appropriate to the scale of the job.
It is not our purpose in this book to teach you how to program, only how to program
better. We assume you are familiar with such fundamental concepts as variables,
conditional statements (e.g., if-then-else, case), iteration primitives (e.g., for-do,
while-do, repeat-until), subroutines, and functions. If you are unfamiliar with these
concepts you may have picked up the wrong book, but buy it anyway for later use.
It is important to realize how much power there is in what you already know. In
principle, every interesting algorithm/program can be built from what you learn in a
first programming course. The powerful features of modern programming languages are
not really necessary to build interesting things – only to do them in cleaner, better
ways.
To put it another way, one becomes a good writer not by learning additional vocabulary
words but by finding something to say. After one or two programming courses,
you know all the words you need to make yourself understood. The problems in this
book strive to give you something interesting to say.
We offer a few low-level coding hints that are helpful in building quality programs.
The bad examples all come from actual submissions to the robot judge.
• Write the Comments First — Start your programs and procedures by writing a
few sentences explaining what they are supposed to do. This is important because
if you can’t easily write these comments, you probably don’t really understand
what the program does. We find it much easier to debug our comments than our
programs, and believe the additional typing is time very well spent. Of course,
with the time pressure of a contest comes a tendency to get sloppy, but do so at
your own risk.
• Document Each Variable — Write a one-line comment for each variable when
you declare it so you know what it does. Again, if you can’t describe it easily, you
don’t know why it is there. You will likely be living with the program for at least
a few debug cycles, and this is a modest investment in readability which you will
come to appreciate.
• Use Symbolic Constants— Whenever you have a constant in your program (input
size, mathematical constant, data structure size, etc.) declare it to be so at the
top of your program. Horribly insidious errors can result from using inconsistent
constants in a program. Of course, the symbolic name helps only if you actually
use it in your program whenever you need the constant. . .
• Use Enumerated Types for a Reason— Enumerated types (i.e., symbolic variables
such Booleans (true,false)) can be terrific aids to understanding. However, they
are often unnecessary in short programs. Note this example representing the suit
(club, diamond, heart, spade) of a deck of cards:
switch(cursuit) {
case ’C’:
newcard.suit = C;
break;
case ’D’:
newcard.suit = D;
break;
case ’H’:
newcard.suit = H;
break;
case ’S’:
newcard.suit = S;
...
No additional clarity arises from using the enumerated variables (C,D,H,S)
over the original character representation (’C’,’D’,’H’,’S’), only additional
opportunities for error.
• Use Subroutines To Avoid Redundant Code — Read the following program fragment
managing the state of a rectangular board, and think how you might shorten
and simplify it:
...
while (c != ’0’) {
scanf("%c", &c);
if (c == ’A’) {
if (row-1 >= 0) {
temp = b[row-1][col];
b[row-1][col] = ’ ’;
b[row][col] = temp;
row = row-1;
}
}
else if (c == ’B’) {
if (row+1 <= BOARDSIZE-1) {
temp = b[row+1][col];
b[row+1][col] = ’ ’;
b[row][col] = temp;
row = row+1;
}
}
...
In the full program, there were four blocks of three lines each moving a value to a
neighboring cell. Mistyping a single + or − would have lethal consequences. Much
safer would be to write a single move-swap routine and call it with the proper
arguments.
Make Your Debugging Statements Meaningful — Learn to use the debugging
environment on your system. This will enable you to stop execution at a given
statement or condition, so you can see what the values of all associated variables
are. This is usually faster and easier than typing in a bunch of print statements.
But if you are going to insert debugging print statements, make them say something.
Print out all relevant variables, and label the printed quantity with the
variable name. Otherwise it is easy to get lost in your own debugging output.
Most computer science students are now well-versed in object-oriented programming,
a software engineering philosophy designed to construct reusable software components
and exploit them. Object-oriented programming is useful to build large, reusable programs.
However, most of the programming challenge problems in this book are designed
to be solved by short, clever programs. The basic assumption of object-oriented programming
just does not apply in this domain, so defining complicated new objects (as
opposed to using predefined objects) is likely to be a waste of time.
The trick to successful programming is not abandoning style, but using one
appropriate to the scale of the job.
0 Comments:
Post a Comment
Subscribe to Post Comments [Atom]
<< Home