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