Week
2
CS 161: Introduction to Computer Science
1
Top Down Design
• The
first main step is problem solving followed by implementation. As part of
problem solving, you need to make sure your problem is thoroughly specified,
then design an algorithm, and before you start coding sit down and do some desk
checking. This verifies that the problem is correctly solved as stated before
you start figuring out how to convert your algorithm into C++!
• Once
you have implemented your program -- i.e., coded your algorithm into C++, any
problems that are embedded -- either by typos or by not thoroughly desk
checking your algorithm -- are called bugs. The process of eliminating bugs is
called DEBUGGING!
•
There are many types of bugs. SYNTAX errors are generally caught by the
compiler; error messages will appear on the screen and an executable file will
not be created. A syntax error means that you have a grammar or punctuation
problem (no period after the END, no semi-colon after a statement, a variable
is not declared, an incorrectly spelled word, etc.). A syntax error means your
program does not follow the rules we have learned about here in class.
•
Another type of bug is a RUN TIME ERROR. This is where your compiler doesn't
find any errors and properly creates an executable file. A run time error is
detected when you try to run your program. For example:
If you try to divide by zero.
• If
there are no run time errors, you can't be guaranteed that your program is BUG
FREE; it might have a LOGICAL ERROR. This means your program doesn't properly
represent the algorithm you created -- or you didn't thoroughly desk check your
algorithm and it doesn't completely solve the specified problem. Logical errors
are the hardest to fix. The computer doesn't know you have an error, only you
can figure out if your program does what it is supposed to be doing. When
testing out a tic-tac-toe program, you have to check if there is a winner in
all possible locations. If you forget to check if there are all X’s in the top
row (like I did), then you can have a winning situation but a Cat Scratch error
is displayed. This is what is called a logic error.
• When
you are debugging a program (from syntax, run time, or logical errors) it is
useful to step through your program on paper (this is called a listing!). Even
here, it is useful to DESK CHECK your program with pencil and paper to see if
you give it certain test data, whether it will create the correct result. Make
sure the output produced IS CORRECT!! Just because there is output doesn't mean
it is anywhere NEAR correct!
Creating an Algorithm...and Program
Development
• To
solve a problem...the first step is to break down the task into subtask...and
then decompose each subtask into smaller and smaller tasks until the smallest
subtask ends up being trivial to implement.
• FOR
EXAMPLE....
Let's say the problem you are given to
solve is:
You want to calculate the grade point
average for a student for the Fall quarter given the grades that were received
(limit the student to taking no more than 5 classes at any one quarter)
(1) Let's design the algorithm. To do this
let's start breaking the task down into smaller and smaller subtasks: (ignoring
the credit hours for each grade!)
Subtask
#1) Obtain the information on what grades were received in each class ...
and how many classes were taken.
Subtask
#2) Calculate the GPA
Subtask
#3) Give the student his result
(2) Breaking Subtask #1 down, gives us the
following algorithm: pseudo code!
1a. Ask the user how many courses were
taken (prompt)
1b. Read the information from the keyboard
1c. For each course, ask the user for the
grade received (prompt the user), where an A=4.0, B=3.0, C=2.0, D=1.0, and
F=0.0.
1b. Read the information from the keyboard
(3) Breaking Subtask #2 down, gives us:
2a. Calculate the GPA by adding the grades
together
2b. Then set the GPA by dividing by the
number of classes taken
(4) Breaking Subtask #3 down, gives us:
3a. Print the result of the GPA
•
After verifying the algorithm, put each subtask into pseudo code ... then rewrite
it into a high level programming language.
#include <iostream>
using namespace std;
int main()
{
...fill in the variable declarations
later...
//Put the algorithm for subtask#1 in
comments here!
cout <<"Please Enter the
number of courses taken Fall 1991:
";
cout <<endl;
cout <<"Then press
RETURN" <<endl;
cin >>number_of_courses;
cout <<" Please Enter the
grades for 5 classes" <<endl;
cout <<" If you have
fewer than 5 classes, enter 0 for those grades";
cout <<endl;
cin >>grade1 >>grade2
>>grade3 >>grade4 >>grade5;
//Put the algorithm for subtask #2
in comments here!
sum_grades = grade1 + grade2 +
grade3 + grade4 + grade5;
gpa = sum_grades / number_of_courses;
//Put the algorithm for subtask #3
here
cout <<"The GPA for
" <<number_of_courses;
cout <<" classes this fall
was " <<gpa <<endl;
return 0;
}
•
(Note...we should also include echoing the input ... to verify to the user that
we are doing the GPA calculation with the correct information)
• Now
we know what variables we used...so edit the program and add their declaration
to the beginning:
float number_of_courses, grade1, grade2,
grade3,
grade4, grade5, gpa,
sum_grades;
•
Notice a blank line separates the code from each major subtask.
Desktop Testing
•
Remember, always test your program mentally before you convert your pseudo code
algorithm into C++ code. It can save you time in the long run.
Always write down your English pseudo
code...and go thru a trial run with example data prior to coding! Verifying that your program is correct first
will save alot of time entering, debugging, and modifying your programs
Comments
• To
make your program understandable, we put notes at key places in the program. These
are called comments. All high level languages have comments.
• C
has only block comments (they start with /*
and then when you are doing commenting you end with a */)
• C++ and
Java have both block comments and end of line comments. Block comments start
with /* and end at some point with */
End of line comments start with a // (with no spaces in between) and
then the rest of the line is taken as a comment.
• With
block comments, anything in between is ignored by the compiler; you can write
as much as you want, explaining your program.
•
Comments can be placed anywhere in your program...but NOT inside a quoted
string...
...You don't want to put comments in the
middle of statements (even though it is allowable!). If you must put the
comment on the same line as a piece of code, put it after the statement is
complete using the // form:
X = Y + Z; //
Taking the Sum of Y and Z
DO NOT Say: X /*The Result*/ = Y + /*Summing operation*/ Z;
• This
is legal:
/* Programming Assignment #1
CS 161
Karla S. Fant
The purpose of this program is to........
The algorithm to solve this problem is............
*/
This is also legal:
// Programming Assignment #1
// CS 161
// Karla S. Fant
//
// The purpose of this program is
to......
• THERE
SHOULD BE NO SPACES between the * and /
• The
first comment in a program should describe (a) What assignment this is, who you
are, what class you are taking. (b) Explain what the program is supposed to do
--- i.e., what was the assignment? This
is also a good place to put your algorithm.
Keep Style in Mind
•
Don't go so overboard with comments that you hide your program. If you have a lot
to say, make sure there are blank lines and spaces surrounding them...so the
reader can clearly determine what a comment is and what the code is. We will
develop a particular style this term of programming to encourage readable and
maintainable programs. We will get a chance to examine programs that make use
of spaces, blank lines, and comments – and those that do not.
• Your
comments should assert what you expect to have happened at any particular point
in a program. Comments should also tell
the reader of the program what the next few statements of code expect to
accomplish.
Forgetting a Closing Comment Delimiter
with Block Comments
• If
you forget the */ after a comment -- watch out. Some of your code will be taken
as a comment until a */ is found. Sometimes, you might get an error
message...but other times your code will just be eaten up! If you don't check
your output (verification) you might never know that some code was missing.
Statements and Blocks
• A
statement is an expression (like i=i+1;) followed by a semicolon. Semicolons
are the statement terminator. C, C++ and Java all support statements that have
this format. The use of semicolons is vital to specify the end of a statement.
If you forget a semicolon, these languages will think you are not yet done with
your thought. A syntax error is likely!!
•
Compound statements in C, C++, and Java are statements inside of {} brackets.
Anywhere you can have a single statement -- you can substitute a compound statement
for it.
• You
don't need a semicolon after the {} pair.
Control Structures
• So
far, the programs we have been talking about have been designed to perform a
particular function -- like calculate a grade point average, play tic-tac-toe or
convert Celsius to Fahrenheit. But, programs are best designed when you can
choose one of two alternatives depending on what is input from the use. For
example, if the user inputs Celsius, the program converts it to Fahrenheit;
but, if the user inputs Fahrenheit, the program converts it to Celsius. All
within the same program!
• You
can do this with a conditional structure which is composed of a logical
expression. In C, C++, and Java this is done with an if statement. An if
statement, starts with the keyword if and then is followed by mandatory
parentheses. Inside the parens is some condition that evaluates to either true
or false.
• You
will get a chance to examine many uses of conditional structures that allow us
to do one thing versus another. With tic-tac-toe, we use an if statement to
find out if the player selected a location that was outside of the board:
bool out_of_bounds = false;
// not out of bounds …
if (x <
start ) //out of bounds
out_of_bounds
= true; //a Boolean variable
else if (x > end) //to far to the
right
out_of_bounds = true;
This says that if the x
coordinate supplied is less than the left side of the game board or if the x
coordinate supplied is greater than the right side of the game board, then the
player has clicked the mouse outside of the game board.
Here
is another simple example:
cout <<"Enter C for
Celsius to Fahrenheit conversion" <<endl;
cout <<"or, enter F for
Fahrenheit to Celsius conversion: " <<endl;
cin >> conversion; <--- declared as a char
cout <<"Enter in the
degrees you want to convert: " <<endl;
cin >> temp; <--- declared
as a float
if
(‘C’ == conversion) //then
convert to Fahrenheit
newtemp
= 9.0/5.0*temp+32.0;
else //otherwise,
convert to Celsius
newtemp
=5.0/9.0*(temp-32.0);
• THE
SYNTAX diagram for a conditional structure: (Notice the reserved words are
lower-case!)
if
<conditional expression>
<statement
executed if condition is true>
else
<statement executed if condition is
false>
•
NOTICE THE SEMICOLONS! Every statement must be followed by a semicolon.
• If
you want more than one statement to occur after the if or after the else then
you must use a compound statement or a block; A compound
statement is one which begins with {
and ends with }. One or more
statements may occur within this block; where each statement must be terminated
by a semicolon.
if
(‘C’ == conversion) //then convert to
Fahrenheit
{
cout <<” Let’s convert
Celsius to Fahrenheit” <<endl;
newtemp
= 9.0/5.0*temp+32.0;
}
else //otherwise,
convert to Celsius
{
cout
<<” Let’s convert Fahrenheit to Celsius” <<endl;
newtemp
=5.0/9.0*(temp-32.0);
}
Notice, with the addition of the else our
syntax diagram could have been:
if
<conditional expression>
<one
statement or a compound statement...
executed
if condition is true>
else
<one
statement or a compound statement...
executed
if condition is false>
• This
means that either the first set of statements is executed when running your
program OR the second set of statements is executed. BOTH sets of statements
are NEVER used. ONE OR THE OTHER!
If
the comparison is true - the first set is used;
If
the comparison is false - the second set is used;
• The
comparison operators may be:
Relational Operators:
>
for greater than
<
for less than
>= for greater than or equal
<= for less than or equal
Equality Operators:
==
for equal to
!=
for not equal to
•
Remember to use semicolons after each statement; if and else are
considered to be reserved words.
Logical Expressions
• For
an if structure, a conditional
expression must occur after the if and before the statement or
compound statement that you wish to have executed. When an if is encountered during execution, the conditional expression
after the if is evaluated.
• In C
and C++, if the conditional expression is non-zero it means it is TRUE. In this
case, the statement or set of compound statements following the expression is
executed; unlike Pascal you do not say "THEN".
Otherwise, if the conditional expression
evaluates to zero it means it is FALSE. In this case, if there is an else the statement or set of compound
statements following the else is
executed. If there is no else then
nothing is done if the conditional expression evaluates to zero (i.e., FALSE).
For example, I could display an error
message if I entered in a value of zero for my age:
int age;
cout << “Please enter your age: “; //This is called a prompt
cin >> age; //Read in the age
if (age != 0)
cout <<”Excellent, you entered
“ <<age <<endl;
else
cout <<”Invalid!”
<<endl;
Another
way to do this in C and C++ would be:
if (age) //if
age is non-zero it is TRUE!
cout <<”Excellent, you entered
“ <<age <<endl;
else
cout <<”Invalid!”
<<endl;
• In
Java, however, zero versus non-zero have nothing to do with the notion of TRUE
or FALSE. So, you need to use care when going between these languages.
Use Care
• UPPER
case characters are treated differently than lower case letters. So if I had
typed in a lowercase 'c' in the previous Celsius example, the program would
have assumed I wanted to convert to celsius, instead of the other way around.
• So, BE CAREFUL to have...
a. clear and precise
prompts! Can anyone think of a better prompt?
b. If the program asked for a C then enter
in a C...not a c
•
Also, integers are stored in the computer exactly but real numbers are stored
as approximations. That means it is very risky to use a real number in a
comparison of using '==' (equality) or '!=' (not equal); instead, use less
than....greater than comparisons since you really don't know how the real
number is EXACTLY stored. EXACT EQUALITY is what the '==' means!
• A
common error with C and C++ is to mistype the number of = symbols when
perfoming a comparison. If you wanted to compare age to zero, you could say:
if (age == 0)
cout <<”Bad!”;
or,
if (!age) //see the next section for what this means!!
cout <<”Bad!”;
but, watch
out if you say this:
if (age = 0) //you just SET your age TO ZERO. Yikes!
Logical Operators
•
There are 3 logical (boolean) operators:
&& And Operator
(operates on two operands)
|| Or Operator (operates on two operands)
! Not Operator (operates on a single
operand)
&& (And) evaluates to true if both
of its operands are true; otherwise it is false. || (Or) evaluates to true if
one or the other of its operands are true; it evaluates to false only if both
of its operands are false. ! (NOT) gives the boolean complement of the operand
(only 1 operand). If the expression/operand was true -- then a NOT will change
it to false; etc.
Again, you will need to use care – because
everything needs to be spelled out. There are no short cuts.
• Here are some examples using ANDs and Ors
//In this case, we want to accept either
upper or lower case characters:
if
(‘C’ == conversion || ‘c’ == conversion) //then
convert to Fahrenheit
newtemp
= 9.0/5.0*temp+32.0;
else //otherwise,
convert to Celsius
newtemp
=5.0/9.0*(temp-32.0);
• Remember there are no short cuts. In
class we will examine some incorrect combinations that will surprise you. Just
make sure to spell it all out
• Here is another example from our
tic-tac-toe program. If I want to find out if my mouse click occurred out of
bounds, I could perform the entire comparison in one if statement:
if
(x < start || x > end) //out of
bounds
out_of_bounds = true;
•
Designing programs in many cases is like art. You can examine the problem from
many perspectives. In the case above, we wanted to know if we were out of
bounds. But, what if we wanted to determine if the mouse click occurred inside
the board limits instead of outside (think of the glass half full rather than
the glass half empty….)
if
(x > start && x < end && y > start && y <
end)
//The mouse click occurred within
the game board!
out_of_bounds = false;
Remember…there
are no short cuts. Notice how I had to spell everything out in the above line!
Here are some other examples…
Conditional Expression Logical value True/False
(5 == 10) && (30 < 88) 0 False
(5 == 10) || (30 < 88) 1 True
!(5==10) && (30 < 88) 1 True
You can also use the ! to negate the value of an expression:
40 != 44 1 True
!(40 != 44) 0 False
Examples
• A couple of quick examples:
//This program displays the smallest of two numbers entered in;
//If both numbers are the same, a special message is displayed
# include <iostream >
using namespace std.
int main()
{
int first, second;
cout <<"Please enter two integers\n";
cin >>first >>second;
if (first > second)
cout <<”The smallest number is: “
<<second <<endl;
else if (first == second)
{
cout << “Both numbers are the same”
<<endl;
else
cout <<”The smallest number is” <<first
<<endl;
return 0;
}
//If we had said the
following…..it would be wrong:
if (first = second) //THIS IS WRONG!!!!!!!!!
….
The dangling else problem
• The
problem of not properly matching your ifs with your elses is common to many
languages.
• What
if we had:
#include <iostream>
using namespace std;
int main()
{
int x, y;
x = 47;
y = -x;
if (x == 0)
if (y == 0)
cout <<"Error...\n";
else //incorrect
indentation!
cout <<"x+y is: " <<x+y
<<endl;
return 0;
}
• Nothing gets printed.
The proper code is:
#include <iostream>
using namespace std;
int main()
{
int x,y;
x = 47;
y = -x;
if (x == 0) //
this could also be written if (!x)
{
if (y == 0) //
this could also be written if (!y)
cout <<"Error...\n";
}
else
cout <<"x+y is: " <<x+y
<<endl;
return 0;
}
This results in:
%a.out
x+y is: 0