oop notes

Document Sample
oop notes Powered By Docstoc
					C++ Notes: Switch statement
The switch statement chooses statements to execute depending on an integer value. The same effect can be achieved with a series of cascading if statements, but in some cases the switch statement is easier to read, and some compilers will produce more efficient code. The break statement exits from the switch statement. If there is no break at the end of a case, execution continues in the next case, which is usually an error.
switch (expr) { case c1: statements break; case c2: statements break; case c2: case c3: case c4: statements break; default: statements } // do these if expr != any above // do these if expr == any of c2, c3, or c4 // multiple values can share same statements // do these if expr == c2 // do these if expr == c1

Equivalent to if statement
The example switch statement above can be written as the following if:
if (expr==c1) { statements } else if (expr==c2) { statements } else if (expr==c2 || expr==c3 || expr==c4) { statements } else { statements }

The unusual situation of one case falling into another without a break statement can not be as easily translated into an if statement; either extra tests or the forbidden goto must be used.

6/29/2009 1

C++ Notes: Example - Loop - Line of stars - count up
This program reads an integer and prints a line with that number of stars (asterisks). A new variable, i, is used to count from 1 up to n. The outer loop reads these integers until an EOF or bad input.

Implemented as a while loop
1 2 3 4 5 6 7 8 9 // loops/line-of-stars-up.cpp - Read int and print that many stars on a line. // Fred Swartz = 1003-08-23 #include <iostream> using namespace std; int main() { int n; while (cin >> n) { //--- Loop counting int i = 1; while (i <= n) { cout << "*"; i++; } cout << endl; } return 0; }

i up from 1 to n. // Initialize counter. // Test counter. // Increment counter.

The text from the above example can be selected, copied, and pasted into an editor.

Implemented as a for loop
The most common way to write a loop that counts is the for loop because it combines the intitialization, testing, and increment in one statement. This makes the program easier to read and maintain. Here is the inner while loop rewritten as a for loop.
for (int i=1; i<=n; i++) { cout << "*"; 2} 1 3

C++ Notes: Loop Example - Line of stars - count down

This program reads an integer and prints a line with that number of stars (asterisks). It counts down from the number it reads in. The outer loop reads these integers until an EOF or bad input.

Implemented with a while loop
1 2 3 4 5 6 7 8 // loops/line-of-stars-down.cpp - Read int and print that many stars on a line. // Fred Swartz = 1003-08-23 #include <iostream> using namespace std; int main() { int n; while (cin >> n) { //--- Loop counting n down to 0. while (n > 0) { cout << "*"; n--; } cout << endl; } return 0; }

The text from the above example can be selected, copied, and pasted into an editor.

Implemented as a for loop
Because the variable n already has a value when we start the inner loop, there is no need for an initialization clause. The for statement requires three clauses separated by semicolons; just leave any unneeded clause blank.
1 2 3 while (cin >> n) { for ( ; n > 0; n--) { cout << "*"; } cout << endl; }

The text from the above example can be selected, copied, and pasted into an editor.

C++ Notes: Loop Example - Maximum of input numbers
Often a cin loop can contain all of the computation for simple programs. Here are two ways to solve a common problem - find the maximum value in a series of numbers. The first solution contains the heart of the correct solution, but it has some weaknesses. The second solution improves on the first.

Max with some problems 3

1 2 3 4 5 6 7 8 9

// loops/cin-max-flakey.cpp - Finds max int in input. // Purpose of this example. // 1. To illustrate algorithm to find maximum. // 2. To show common problems to be fixed in loops/cin-max-robust.cpp // Eg, what happens if all numbers are negative? No input? // Fred Swartz - 2003-08-28 #include <iostream> using namespace std; int main() { int max = 0; int n; while (cin >> n) { if (n > max) { max = n; } } cout << "Maximum is " << max << endl; return 0; }

10 The text from the above example can be selected, copied, and pasted into an



Max with some improvements
The following program checks to make sure there is at least one number to be read. Also, it uses the first value to initialize the maximum, which guarantees that it will work regardless of the range of values.
1 2 3 4 5 6 7 8 9 10 // loops/cin-max-robust.cpp - Finds max int in input. // Purpose of this example. // 1. To illustrate algorithm to find maximum. // 2. To show solution to negative number or missing input. // Fred Swartz - 2003-08-28 #include <iostream> using namespace std; int main() { int max; int n; if (cin >> max) { // Sets initial value of max while (cin >> n) { if (n > max) { max = n; } } cout << "Maximum is " << max << endl; } else { cout << "No input!" << endl; } return 0; }

The text from the above example can be selected, copied, and pasted into an


11 editor.

Another way to insure that the maximum is correctly initialized is to set it to the minimum possible int value. The range of an int depends on the the compiler and underlying machine architecture, but the minimum value is in INT_MIN (from header file <climits>). But there is still the problem of no input values.

C++: Programming Problem - cin Count Input Values
(10 points) Write a program which reads a sequence of integers and counts how many there are. Print the count. For example, with input 55 25 1004 4 -6 55 0 55, the output should be 8 because there were eight numbers in the input stream. Your program should work for any input, not just this example..

C++: Programming Problem - cin Count Equal
(10 points) Write a program which reads a sequence of integers and counts how many times the number 55 occurs. Print the count. For example, with input 55 25 1004 4 -6 55 0 55, the output should be 3 because there were 3 55's in the input stream. Your program should work for any input, not just this example..

C++: Programming Problem - cin Averag
(10 points) Write a program that reads daily temperatures, as floats. Read in a loop until an EOF. After the input has been read, print the average value. Sample input values
10.0 11.3 4.5 -2.0 3.6 -3.3 0.0

The output should look something like the following. Formatting may vary.
Average = Average is 3.44286


No input. If there is no input, your program might try to divide by zero, which is a very bad idea. How will you prevent this problem?

C++: Programming Exercise - Average Positive Negative
Write a complete program which reads floating point numbers from cin and computes two averages: the average of the negative numbers it reads and the average of the positive numbers it reads. For example, for input 9 -1 -1 -4 1 the positive average would be 5 (the sum of the positive numbers (9+1) divided by the number of positive numbers (2). By a similar process the average of the negative numbers would be -2 (ie, ((-1 + -1 + -4) / 3). You don't need to write any functions for this problem.


C++: Programming Problem - Print Numbers
(5 points) Write a loop to print all numbers from 1 to 100, one per line, Write a blank line after every five lines. Hint Use the mod opertor (%) to determine every fifth line, eg,
if (lineNumber%5 == 0) . . .

C++: Programming Problem - Ulam Sequence
The Ulam Sequence
A mathematician named Ulam proposed generating a sequence of numbers from any positive integer n (n > 0) as follows:
   

If n is 1, stop. If n is even, the next number is n/2. If n is odd, the next number is 3*n + 1. Continue with this process until reaching 1.

Here are some examples for the first few integers.
2 -> 1 3 -> 10 -> 5 -> 16 -> 8 -> 4 -> 2 -> 1 4 -> 2 -> 1 5 -> 16 -> 8 -> 4 -> 2 -> 1 6 -> 3 -> etc as for 3 above. 7 -> 22 -> 11 -> 34 -> 17 -> 52 -> 26 -> 13 -> 40 -> 20 -> 10 -> 5 -> see 5 above.

Ulam hasn't been the only one to work on this problem. See The 3x+1 problem and its generalizations for more information.

Does every sequence stop?
It's unknown if all sequences end at 1. Perhaps there are sequences that get into a loop, or increase indefinitely.

Write a program that shows the sequence
Write a program that reads a number (in a while loop of course) and prints the Ulam sequence for it.

Possible extensions
There are several ways to extend this program. a. Instead of reading input, write a for loop that examines the length of the Ulam sequence for the first 1,000 numbers. Which number produces the longest sequence, and how long is it? Or do some sequences never terminate? b. Some intermediate numbers become quite large. What is the largest number that is ever encountered in the Ulam sequences for the first 1,000 numbers?


C++: Programming Problem - Print Parallelogram
Name __________________________________ (10 points) Write a program which reads an int, then prints a parallelogram with edges that are that size. For example, when it reads the number 5, the output would be
***** ***** ***** ***** *****

 

This is most easily solved using nested for loops (the outer loop for the row, and loops inside for the column. Each row will has one more blank at the beginning than the previous row. You can use a for loop to print the blanks, then a for loop to print the stars.

C++: Programming Problem - Figures
Here are some classic programming problems that require the use of nested loops. A frequent textbook problem is to draw figures using characters. If you already know how to define functions, you might find it useful to write convenience functions to help you. You're welcome to change the appearance of these, or produce something a little different. The point of this is to give you practice with loops and functions, so show what you can do. 1. Print a rectangle. Read a height and width and print a rectangle with that height and width. This example output has height 3 and width 7.
2. 3. 4. ******* ******* *******

Sample solution.
int width, height; while (cin >> width >> height) { for (int row=0; row<height; row++) { for (int col=0; col<width; col++) { cout << "*"; } cout << endl; // end the line of stars. } }

5. Print a triangle. Read a number and print a triangle of that size. This example is of size 6.
6. 7. 8. 9. 10. 11. * ** *** **** *****



Here is a solution.
int size; while (cin >> size) { for (int row=1; row<=size; row++) { for (int col=0; col<row; col++) { cout << "*"; } cout << endl; } } // end the line.

12.Print a triangle. Read a number and print a triangle of that size. This is a little different than the problem above because you'll have to print some spaces at the beginning of each line. This example is of size 6.
13. 14. 15. 16. 17. 18. * ** *** **** ***** ******

19.Print a rectangle outline. Read a height and width and print a rectangle that looks like the one below. This example has a height of 5 and width of 7. You might choose one of two approaches to this problem. 1. Break it down into three problems: a line of stars; lines consisting of a star, blanks, and a star; and again a line of stars. 2. At each position write either a star or blank. Use an if statement to test for first or last row of first or last column, in which case a star is printed, otherwise print a blank.
20. 21. 22. 23. 24. ******* * * * * * * *******

25.Print a pyramid. Read (in a loop of course) a number, n, and print a pyramid that has that size. The example below shows what would be printed for n=4.
26. 27. 28. 29. * * * * * * * * * *

30.Print a parallelogram. Again read n in a loop. For each value of n produce output that makes a parallelogram like the following for n=6. You might find it easier to solve this to breaking the problem into two simpler problems: eg, thinking of this as an upper triangle and a lower triangle.
31. 32. *


33. 34. 35. 36. 37. 38. 39. 40. 41.

** *** **** ***** ****** ***** **** *** ** *

C++: Programming Problem - Multiplication Table
Write a program to read a number from the user (in a loop of course), and print a multiplication table up to that number. Hints

This is most easily done using nested for loops, ie a for loop do go down the rows, which contains a for loop to go accross the columns.

Example output in increments
As usual, the best approach is to use incremental development. Here are three stages you might want to go thru. 1. The smallest possible output. But it's ugly with unaligned columns.
2. 1 2 3 4 5 3. 2 4 6 8 10 4. 3 6 9 12 15 5. 4 8 12 16 20 6. 5 10 15 20 25

7. To make the multiplication table look nice, the I/O manipulator setw() can be used to set the minimum width of the converted form of the number.
8. #include <iomanip> 9. . . . 10. cout << setw(4) << n;

This will right-align the value of n in a field of four spaces. The output would look like this.
1 2 3 4 5 2 4 6 8 10 3 6 9 12 15 4 8 12 16 20 5 10 15 20 25

11.Add column and row headers as well as separating lines to make it look like the following. Several additional loops are required to print the column header and horizontal separating lines. Don't try to make all of these additions at once. For example, first add the row header and vertical bars. Get that running then print the separating lines. Lastly add the column header. The order of these additions


isn't important in this case, but to work on small increments in the program makes development to more easily.
12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 1 | 2 | 3 | 4 | 5 | 1 1 | 2 | 3 | 4 | 5 | 2 2 | 4 | 6 | 8 | 10 | 3 3 | 6 | 9 | 12 | 15 | 4 4 | 8 | 12 | 16 | 20 | 5 5 | 10 | 15 | 20 | 25 | +-----+-----+-----+-----+-----+ +-----+-----+-----+-----+-----+ +-----+-----+-----+-----+-----+ +-----+-----+-----+-----+-----+ +-----+-----+-----+-----+-----+ +-----+-----+-----+-----+-----+

C++ Notes: Function Concepts
Purpose of functions
The purpose of functions is to make the programmer's life easier.  Write code once, and call it from many places. This insures consistency, and reduces the cost of writing and debugging.  A function allows code to be parameterized by passing values to it.  Functions can be collected in libraries and reused in other programs.  Functions create new conceptual units that form the units that programmers use in thinking about a problem.

For a function to work well as a conceptual unit it has to have a name that is clear to the human reader.  Choose a name that has a clear meaning. Eg, "f" is not a good name.  Void functions are more readable if a verb name is used that describes what it does. Eg, "printAverage" would be a good name for a void function that prints the average of some numbers. "Average" would not be a good name for it.  Value-returning functions


A verb is a good choice for a value returning function that performs an operation that would naturally be understood to produce a value, eg, "add(x, y)". A noun which describes the the result can be used. For example, "remainder(a, b)" would be a good choice for a function that computes the remainder after division (ie, what the "%" operator does). The noun is a good choice if you're tempted to add a word like "compute" or "calculate" in front (eg, "computeRemainder(a, b)"). The "compute" or "calculate" is simple often omitted if the meaning is clear. Getter and setter functions. Prefix functions which get a value from an object or data structure with "get" (eg, getTime()). Similarly use "set" for functions that set values (eg, setTime()).



boolean functions should usually start with "is" or another word that suggests a yes/no answer. Eg, "isOdd(n)" is a good name for a function that returns true if its parameter is odd, and it's better than simply "odd()". Case. There are several conventions, but whichever one you choose, be consistent to make programs readable. The most common convention is to start names with lowercase and capitalize the first letter of each additional word in the name. Some programmers start functions with uppercase characters, but this is less common.

Each function should do only one thing. This should be done so that the conceptual unit can be understood easily. Sometimes it will be convenient to do two things in a function because you're working on the same data. Try to resist this temptation. Make two functions if you reasonably can. Separate I/O and computation. Greater cohesion is almost always achieved by separating I/O and computation. If possible, put the I/O in main or in separate functions. If I/O is properly separated, the same functions which make up a program can be used either in a GUI or command-line program.

Functions should avoid side-effects such as communicating by means of global variables. Use of global variables increases coupling, which makes programs harder to debug and maintain.

Functional Decomposition - top-down programming - successive refinement
The top-down programming style is to write a short main program that calls on additional functions to accomplish it task. These functions should similarly be kept short and call more functions if necessary to get their task done. Start with the main function, and write only function stubs which do almost nothing except maybe print a message that they were called. Get this running, then expand one of the stubs, get this running, ... . This very productive style of programming is related to iterative programming and is one of the cornerstones of Extreme Programming. Top-down programming is good for for small programming tasks. A better approach for larger programs is to divide them into objects.

Size - One page
It is a good idea to keep functions shorter than one page or one screen. This makes them easy to comprehend, If you want to make them larger, think about how you could break the processing into two or more functions (top-down programming).


Value parameters copy the actual parameter value into the formal parameter. Changes to the formal parameter, which is a local variable, do not get passed back to the calling program.



Reference parameters are implemented by passing the memory address of the actual parameter to the formal parameter. Reference parameters are used to pass values back from a function. This is necessary to return more than one value. It is helpful to have a clear idea of the direction of data flow of each parameter: in means the data only flows into the function (typically a value parameter), out means the data only flows out of the function (a reference parameter), or inout means that data flows both into and out of the function thru this (reference) parameter. There is no language support for these ideas in C++ altho these keywords are used in the Ada programming language.


The compiler must know about the return and parameter types before it can understand the call to a function. You should declare all of your function prototypes at the beginning of your program. This is one of the primary purposes of the system include files. If you've written a number of functions in many files, it is common to define your one include file which defines the prototypes.

C++ Notes: Function Structure
Every function (except main) should be declared near the beginning of a program with a prototype which gives the return type (or void), name, and the parameter names and types. Parameter names are not required in prototypes, but they are very useful to readers of your program.
void printChars(char c, int count);

Note that prototypes always end with a semicolon. If you are developing a program with many modules, its common to put the prototypes into an include file. Assuming you are using prototypes, the order of the later function definitions doesn't matter. Prototypes are needed by the compiler to know how many and type of the parameters, and the return value type.

Function Definition
The first line of a function definition (called the function header) is the same at a prototype, except that it is followed by the function body in braces. Neither the header nor the body is followed by a semicolon.
void printChars(char c, int count) { for (int i=0; i<count; i++) { cout << c; } }//end printChars

void functions 12

If a function doesn't return a value (perhaps it changes a reference parameter, changes a global, or produces a side-effect like I/O), it must be declared as void type. In some programming languages (Visual Basic, Pascal, Fortran, ...), void functions are called by a different name (subroutine, procedure, ...).

Local Variables
All variables that are declared in a function are local to the function. They can not be referenced from outside the function (local scope). Their lifetime is the same as the activation of the function: they are created when the function is called and are destroyed when the function returns. They have no initial values so will have whatever value happens to be in memory when they are allocated. Parameters are like local variables (local scope, function lifetime), but are assigned an initial value from the corresponding expression in the function call.

Return statement
The return statement stops execution and returns to the calling function. A void function doesn't need a return statement -- when the end is reached, it automatically returns. However, a void function may optionally have one or more return statements.

C++ Notes: Function
Return statement



The return statement stops execution and returns to the calling function. When a return statement is executed, the function is terminated immediately at that point, regardless of whether it's in the middle of a loop, etc.

Return optional in void functions
A void function doesn't have to have a return statement -- when the end is reached, it automatically returns. However, a void function may optionally contain one or more return statements.
void printChars(char c, int count) { for (int i=0; i<count; i++) { cout << c; }//end for return; // Optional because it's a void function

}//end printChars

Return required in non-void functions
If a function returns a value, it must have a return statement that specifies the value to return. It's possible to have more than one return, but the (human) complexity of a function generally increases with more return statements. It's generally considered better style to have one return at the end, unless that increases the complexity.


The max function below requires one or more return statements because it returns an int value.
// Multiple return statements often increase complexity. int max(int a, int b) { if (a > b) { return a; } else { return b; } }//end max

Here is a version of the max function that uses only one return statement by saving the result in a local variable. Some authors insist on only one return statement at the end of a function. Readable code is much more important than following such a fixed rule. The use of a single return probably improves the clarity of the max function slightly.
// Single return at end often improves readability. int max(int a, int b) { int maxval; if (a > b) { maxval = a; } else { maxval = b; } return maxval; }//end max

C++ Notes: Function Parameters
Formal Parameters
Formal parameters are written in the function prototype and function header of the definition. Formal parameters are local variables which are assigned values from the arguments when the function is called.

Actual Parameters or Arguments
When a function is called, the values (expressions) that are passed in the call are called the arguments or actual parameters (both terms mean the same thing). At the time of the call each actual parameter is assigned to the corresponding formal parameter in the function definition. For value parameters (the default), the value of the actual parameter is assigned to the formal parameter variable. For reference parameters, the memory address of the actual parameter is assigned to the formal parameter.


Value Parameters
By default, argument values are simply copied to the formal parameter variables at the time of the call. This type of parameter passing is called pass-by-value. It is the only kind of parameter passing in Java and C. C++ also has pass-by-reference (see below).

Reference Parameters
A reference parameter is indicated by following the formal parameter name in the function prototype/header by an ampersand (&). The compiler will then pass the memory address of the actual parameter, not the value. A formal reference parameter may be used as a normal variable, without explicit dereference - the compiler will generate the correct code for using an address. Reference parameters are useful in two cases:
 

To change the value of actual parameter variables. To more efficiently pass large structures.

See Reference Parameters.

Additional topics
This summary doesn't cover some features: eg, variable parameter lists, default parameter values,

C++ Notes: Function Call Order
Here is an example that illustrates some of the issues with function calls.

1 2

// functions/call-order.cpp -- Illustrates order of calls. // Fred Swartz 2003-09-02

#include <iostream> using namespace std; 4 //--------------------------------- prototypes int even(int a); 5 int odd(int b); 6 int ulam(int c); 3 //--------------------------------- main 8 int main() { // What does each statement print? 9 cout << odd(4) << endl; 10 cout << (even(2) + odd(3)) << endl; // (Note 1) cout << ulam(ulam(ulam(5))) << endl; // (Note 2) 11 } 12 13 //---------------------------------- even 14 int even(int a) { cout << "even(" << a << ")" << endl; 15 return a/2; 16 } 17 //---------------------------------- odd 18 int odd(int b) { 7


19 20 21 22 23 24 25 26 27 }

cout << "odd(" << b << ")" << endl; return 3*b + 1;

//---------------------------------- ulam int ulam(int c) { cout << "ulam(" << c << ")" << endl; if (c%2 == 0) { return even(c); }else{ return odd(c); } }

28 The text from the above example can be selected, copied, and pasted into an editor.

1. Order Ambiguity. The order of evaluation of operands is not defined in C++ (unlike Java where it's strictly left to right). It's possible for the rightmost call to be made before the leftmost call. Here are two possible orders of execution.

2. // Original: cout << (even(2) + odd(3)) << endl; 3. int t1 = even(2); // left before right operand eval. 4. int t2 = odd(3); cout << t1+t2 << endl;

// Original: cout << (even(2) + odd(3)) << endl; int t2 = odd(3); // right before left operand eval. int t1 = even(2); cout << t1+t2 << endl;
I've see it done both ways in various compilers, so this is a real portability issue. However, the order is only important if both functions have interacting side-effects (I/O, change globals, ...). 5. Use intermediate variables for clarity. If it's difficult to understand an expression, compute it in pieces. The compiler does this internally. One of the above examples can be rewritten.

6. //Original: cout << ulam(ulam(ulam(5))) << endl << endl; 7. int t1 = ulam(5); 8. int t2 = ulam(t1); 9. int t3 = ulam(t2); // the inner call must be made first. // that result is used to make the next call. // only now can we make the outer function call.

cout << t3 << endl << endl;

C++ Notes: Function Reference Parameters
Reference parameters are useful in two cases:

Change values. Use a reference parameter when you need to change the value of an actual parameter variable in the call. When a function computes only one value it is considered a better style to return the value with the return statement. However, if a function produces more than one value, it is common


to use reference parameters to return values, or a combination of the return value and reference parameters.

Efficiency. To pass large structures more efficiently. This is especially common for passing structs or class objects. If no changes are made to the parameter, it is should be declared const.

Reference parameters pass an address, not a value
When you declare a reference parameter, the function call will pass the memory address of where the actual parameter, instead of copying the parameter value into the formal parameter.

Declare reference parameters with a &
To indicate a reference parameter, an ampersand (&) is written in the function prototype and header after the parameter type name. For example,
void assign(int& to, int from) { to = from; } // Will change the actual parameter in the call.

has two parameters, to is a reference parameter as indicated by the ampersand, and from is a value parameter. This ampersand must be in both the prototype and the function header.

Example - Swap (bad solution)
Let's say you want to exchange the values in two arguments.
int a = 5; int b = 10; swap(a,b); // If we want a=10 and b=5 as the result, how do we write the function?

Here's an example that does NOT work correctly, altho there is no error message.
void swap(int x, int y) { x = y; y = temp; } // BAD BAD BAD BAD BAD BAD BAD int temp = x; // temp is a local variable // changes only local copy // changes only local copy

Because x and y are value parameters, like local variables, changes to them have no effect on the calling functions arguments a and b.

Example - Swap (good solution)
If the parameters are marked as reference parameters, the memory address of each argument is passed to the function. The function uses this address to both get and set the value. Here is swap written correctly. The only change is the addition of the & to the parameter declaration following the type.


void swap(int& x, int& y) { int temp = x; x = y; y = temp; } // temp is a local variable // changes the actual parameter in the calling pgm. // changes the actual parameter in the calling pgm.

L-values required for actual reference parameters
An l-value is something that you can assign to. This name is short for left-value, referring to the kind of value that must be on the left side of an assignment statement. All actual reference parameters must have an l-value.
swap(1, 2); swap(x+5, c); swap(x, y); // BAD - literals don't have l-values. // BAD - numeric expressions don't have l-values. // OK - variables are l-values.

swap(a[i], a[i+1]); // OK - array references are l-values.

It's easy to figure this out if you just think about what you can write on the left of an assignment; '1', '2', and 'x+5' are obviously not legal.

C++: Programming Problem - Convert to Seconds
Name: _________________________________ Write a function named toSeconds which takes three integer parameters, a number of hours, number of minutes, and number of seconds and returns the total number of seconds. The prototype should look like.
int toSeconds(int hours, int minutes, int seconds);

As always, use good indentation and meaningful identifier names. Sample output For example,
cout << toSeconds(0, 2, 15);

would print 135, the total number of seconds in 0 hours, 2 minutes and 15 seconds.

C++: Programming Problem - Temperature Opinion
Name: _________________________________ Given this main program:
int main() { float temperature; while (cin >> temperature) { printTempOpinion(temperature); }


return 0; }

Write the function printTempOpinion which prints "Cold" on cout if the temperature is below 70, "OK" if the temperature is in the range 70-80, and "Hot" if the temperature is above 80.

C++: Programming Problem - Convert to Meters
Name: _________________________________ Write a function named toMeters which takes two float parameters, a number of feet and a number of inches and returns the floating point number of equivalent meters. Assume there are 2.54 centimeters (0.0254 meters) in one inch. Write only the function. Sample Usage
cout << toMeters(5, 11);

This would print 1.8034, the number of meters in 5 feet, 11 inches.

C++: Programming Problem - Average 3 Numbers
Name: _________________________________ Write a function named average3 which returns the average of its three floating-point parameters. As always, use good indentation. You do not need to write the main program. Write only the function. For example,
cout << average3(7, 2, 6);

This would print 5.0, which is (7+2+6)/3.

C++: Programming Problem - Prompt Y/N
Name: _________________________________ Write a function named promptYN which takes one string parameter. It prints the string (which is a question the caller supplies) on cout, then prompts the user to enter Y or N. It then reads one character from cin. If the character is a 'Y', the function returns true, if the character is a 'N', it returns false, if the characer is neither of the above, your function should prompt the user again for a 'Y' or 'N' and read another character, continuing with this until a Y or N is entered. The prototype should be the following.
bool promptYN(string question);

Sample Usage For example,
while (promptYN("Do you want to continue")) . . .

would continue executing the loop as long as the user answered Y.

C++ Notes: INPUT/OUTPUT - Overview


and cout can be used for most I/O

One of the great strengths of C++ is that simple I/O is simple. It seems like it should be obviously true, but Java sadly makes simple I/O difficult. To input most values, just use cin (pronounced see-in) and the >> operator. Similarly, for output use cout (pronounced see-out) and the << operator. For example,
int x; int y; cin >> x >> y; cout << "Sum = " << (x+y) << endl;

The input is treated as a stream of characters without regard to spacing or lines. It's also easy to read in a loop.
while (cin >> x) { sum += x; } // Reads until EOF

    

The cin loop End-Of-File (EOF) Reading numbers I/O operators - << and >> Anti-idiom: Testing cin for EOF

Reading individual characters and lines
Because the default stream I/O skips whitespace, to read all characters or to read lines, you have to use some different functions. See
 

Reading characters Reading lines

Reading text files
Reading text files is very easy. It's basically the same as reading from cin, but you have to define a new file input stream and "open" it with a file name. See
 

Reading Text Files Example: File open dialog

Using strings as source and destination of I/O
You can easily use all of the stream I/O capabilities to "read" and "write" using strings. This isn't so commonly done, but it can be very useful. See
 

String streams String stream example

Formatting output 20

The I/O manipulators can be used to format your output, eg, to choose field widths and number of decimals printed. See

I/O manipulators

C++ Notes: Idiom - cin loop
Idiom: Read from cin in a while loop
The standard C/C++ style for reading is to put the read operation in a while loop condition. If the read proceeds correctly, then the value is true. If there is an end-offile (EOF) meaning that the end of the data has been reached, or if there is an error in reading, then the value returned is false and execution continues at the end of the loop.

Example -- Adding numbers in the input
int sum = 0; int x; while (cin >> x) { sum = sum + x; } cout << sum;

Testing the value from an input operation
Using cin in a while loop is a very common style of programming.

Produces a value. The input operation with cin not only reads values into variables, but it also produces a value. That's because >> is an operator that produces a value. This value can be tested in loops and ifs. true. The value of cin >> x is true if a value was read into x. false. The value of cin >> x is false if it was unable to read. There are several possible causes for a reading failure.

 

EOF. When there is no more data, the EOF (End-Of-File) condition occurs. Every stream of input has an end so this is a normal event. It happens when reading a disk file and the end is reached. It's also possible to signal an EOF from the console by entering a special key combination, which depends on which operating system and C++ library you are using. Generally, you can use Control-Z followed by Enter to send an EOF from the keyboard. See End-Of-File (EOF). Bad data. The read may fail if the data isn't formatted correctly. For example, when trying to read a floating-point temperature and the user types "zero", the read will fail.


Use this pattern when reading. Another style, which is not generally used is Anti-idiom - Using cin in three places, instead of one. 21

C++ Notes: Reading numbers
Idiom: Read from cin in a while loop
The standard C/C++ style for reading is to put the read operation in a while loop condition. If the read proceeds correctly, then the value is true. If there is an end-offile (EOF) meaning that the end of the data has been reached, or if there is an error in reading, then the value returned is false and execution continues at the end of the loop.

Example -- Adding numbers in the input
int sum = 0; int x; while (cin >> x) { sum += x; } cout << sum;

Anti-idiom: Checking for EOF instead of reading
The following code does almost the same thing as the code above, but it has disadvantages.
int sum = 0; int x; cin >> x; while (cin) { sum += x; cin >> x; } cout << sum;    // BAD idiom for input. // Required by inadequate Pascal I/O. // Should not be used in C++.

Duplication. The input is read in two places, not one. Duplicate code creates an opportunity to update one and not the other when modifying the program. More code. The reading and testing is split between three lines instead of one. This makes it more difficult to read and maintain.

Possible failure. The GCC I/O library, which is used by DevC++, does a good job with this. However, I've used systems that behaved differently using the while (cin) test, depending on whether there is whitespace after the last value. Think about it. The issue is rather subtle how does the I/O system know that you aren't going to read the blanks after the last value? Well, it can't really know, so it makes some assumptions. Not all systems make the same assumptions about how to handle trailing whitespace after the last value.

C++ Notes: What values do the I/O operators (<< and >>) return?
What values do the I/O operators (<< and >>) return?
C++ allows you to define functions to associate with existing operators. The << and >> operators, whose orginal meanings were bitwise left and right shift, have additional meanings for C++ iostreams. So how do they work?


The >> and << operators are evaluated left-to-right, so the following are equivalent statements, altho writing the parentheses would be rather weird.
cin >> a >> b >> c; (((cin >> a) >> b) >> c); // Same as above.

What value is produced, for example, by (cin >> a)? And I mean what value is produced in the expression, not what value is read into the variable. It calls an overloaded templated function (operator>>) in an istream class which reads input and stores it into the variable on the right. It then returns the left operand (ie, cin) so the result can be used if there is another >> operator. This chaining of the I/O operators is a rather clever solution. Here's an example program that shows this.
if ((cin >> a) == cin) { cout << "Equal" << endl; } else { cout << "Not Equal" << endl; } // Yes, it is true

Why cin can be used as a truth value
It's possible to make tests like
if (cin)

which will be true if cin is ok and false if at an end-of-file or has encountered an error. It's type is istream& (input stream reference), so how can that be used as a truth value. The trick is that when it's evaluated in the context of a condition, eg, in an if or while statement, a special function is called in the istream class. This function returns a value that can be interpreted as true or false.

Reading in the while condition
Because the >> operator returns the iostream (eg, cin), which can be tested for EOF or errors, the cin loop idiom can be used.
while (cin >> x) { . . . }

which effectively tests for EOF, and also that the input is a valid value.

C++ Notes: End-Of-File (EOF)
End-Of-File (EOF) when reading from cin
When a program is reading from a disk file, the system "knows" when it gets to the end. This condition is called End-Of-File (EOF). All systems also provide some way of indicating an EOF when reading from the keyboard. This varies from system to system. Dev-C++ Type: Enter Control-z Enter MS Visual C++ Type: Enter Control-z Enter Enter Reportedly there is a Microsoft patch that can be applied so that only one Enter is required after the Control-z. I wouldn't bother. Other systems


Some may use other characters: control-D then Enter, or control-D followed by a control-Z, or ... .

You can just provide bad data to make cin fail in many cases. A student once claimed that typing "EOF" was the way to indicate and end-of-file from the console. Yes, it stops reading (because of an error) if you're reading numbers, but not when reading characters or strings!

Resetting after EOF
Altho it doesn't make sense to read after an EOF on a file, it is reasonable to read again from the console after an EOF has been entered. The clear function allows this.
while (cin >> x) { ... // loop reading until EOF (or bad input) } cin.clear(); cin >> n; ... // allows more reading

C++ Notes: Reading Characters
These notes are written using cin as an example, but they apply to all input streams.

What about whitespace?
The standard input stream (cin) does just what you want when reading integers, floating point etc. It ignores all whitespace (blanks, tabs, etc) that appears in front of a number. But when you're reading characters, you will often want to read whitespace too. For example, here's a little loop to count the number of characters in the input stream.
char c; int count = 0; // DOESN'T READ WHITESPACE!!!!! count++; } while (cin >> c) {

The fails to give an accurate count of characters because it ignores all the whitespace characters. There are two solutions.

Use the noskipws I/O manipulator to cause a further cin reads to not ignore whitespace (or until the skipws manipulator is used). Here's that same loop rewritten.
  char c; cin >> noskipws; // Stops all further whitespace skipping


 

while (cin >> c) { count++; }

// Reads whitespace chars now.

This isn't a bad solution, but if you need to switch back and forth between skipping whitespace and not, I'd choose the next alternative.
    }

Use the cin.get() function.
char c; while (cin.get(c)) { count++; // Always reads whitespace chars.

Read one line with cin.get(...) or cin.getline(...)
char ca[100]; . . . while (cin.get(ca)) { // ca has one input line without crlf and with terminating 0 . . . }

Ignoring input
When an error is encountered, it is often useful to skip all remaining characters on the line. You can do that with:
cin.ignore(n, c);

where n is the number of characters to skip, and c is the character to skip up to, whichever comes first. For example, to skip to the end of the line,
cin.ignore(1000, '\n');

C++ Notes: String Streams
Like files, strings are a sequence of characters. C++ provides a way to associate an I/O stream with a string. Here are some common uses for string streams. 1. Localizing errors in input. It is common to process one line at a time. The standard input streams proceed to the next line if there are insufficient values on one line. Also, an error in the input may make error recovery difficult. The solution is to read the input one line at a time into a string. Then "read" that string using a string stream. 2. Reading one of two types. Suppose you don't know what type the next input element is - it's either an int or a name. Solution: read it into a string, then try reading from the string as an int. If that fails assume it's a name. Use this to read to a sentinal value. For example, let's say you are reading integers until a certain value. But what value can you use to stop the input? Why not use "STOP" or some other string. Well, you can't do this easily while reading ints from cin, but you can read from cin into a string, compare that string to "STOP", and if it doesn't match, "read" from the string with a string stream as an integer.


3. Converting internal values to their external representations. Sometimes you want a character representation of data in memory. The best facilities for formatting data (eg, numbers) are the output stream facilities. You can create an output stream that goes into a string to make use of the stream fomatting.

String stream input - istringstream
String streams support all the normal iostream capabilities. There are only two additional things you need. 1. Input string streams must be declared istringstream. 2. The string value to read is set with str(). Here is a simple example.
#include <iostream> #include <sstream> using namespace std; . . . int a, b; string s = "34 22"; istringstream ins; // Declare an input string stream. . . . ins.str(s); ins >> a >> b; // Specify string to read. // Reads the integers from the string.

String stream output - ostringstream
Simlarly, there are only a couple of things you need to know to use output string streams. 1. Output string streams must be declared ostringstream. 2. The string value is obtained from the stream with str(). Here is a simple example that puts the character value of the square root of 2 into a string.
#include <iostream> #include <sstream> using namespace std; . . . ostringstream outs; . . . outs << sqrt(2.0); s = outs.str(); // Convert value into a string. // Get the created string from the output stream. // Declare an output string stream.

C++ Notes: String stream example

This example reads lines with an integer, an operator, and another integer. For example,
25 * 3 4 / 2

It's simple to read each of these three elements, but what happens if something is wrong with the input. For example, errors in the input like
25 * 3 + 1 or 25 *

will cause the whole program to fail. The solution is to read each line into a string, then read from the string. This will isolate the errors to one line, which is something that isn't possible with normal stream I/O, which will simply ignore whitespace, including line breaks. The example below shows how to do this.
// sstream-line-input.cpp - Example of input string stream. // This accepts only lines with an int, a char, and an int. 2 // Fred Swartz 11 Aug 2003 1 3 #include <iostream> 4 #include <sstream> #include <string> 5 using namespace std; 6 //================================================================ main int main() { 7 string s; // Where to store each line. int a, b; // Somewhere to put the ints. 8 char op; // Where to save the char (an operator) 9 istringstream instream; // Declare an input string stream 10 while (getline(cin, s)) { // Reads line into s 11 instream.clear(); // Reset from possible previous errors. instream.str(s); // Use s as source of input. 12 if (instream >> a >> op >> b) { 13 instream >> ws; // Skip white space, if any. if (instream.eof()) { // true if we're at end of string. 14 cout << "OK." << endl; } else { cout << "BAD. Too much on the line." << endl; } } else { cout << "BAD: Didn't find the three items." << endl; } } return 0; }

Note that ws is an input manipulator that skips whitespace. The flow could be simplified somewhat by making the if more complicated. Here is the central part rewritten, adding some calculator code.
if ((instream >> a >> op >> b >> ws) && instream.eof()) { switch (op) { case '+': result = a + b; break; case '-': result = a - b; break; case '*': result = a * b; break; case '/': result = a / b; break; default : cout << "Bad operator '" << op << endl; continue; // next loop iteration


} cout << result << endl << endl; } else { cout << "BAD INPUT." << endl; }

Monday, June 29, 2009


Shared By:
Tags: tags
Description: This is notes for suporting students to easy programing in oop c program