Vous êtes sur la page 1sur 14

# ECNG 1009 Introduction to Programming Practical Tutorial LOOPS Loops

Loops are a structure that allows us to repeat a process continuously. What does the following do?
loop1.cpp #include <iostream> int main() { int i = 0; while (i != 5) { std::cout << "The number: " << i << std::endl; i = i + 1; } return 0; }

Can you modify the above to count up to the number 10 starting from the number 3? Can you modify the above to count backwards from 12 to 2? Can you modify the above to output the 7 times tables from 1 till 36? Can you modify the above to output the cube (power of three) of all the numbers from 1 to 10? What does the following do?
loop2.cpp #include <iostream> int main() { for (int i = 0; i != 5; ++i) { std::cout << "The number is: " << i << std::endl; } return 0; }

Is the for loop presented here equivalent to the while loop above?

Can you do all of the above, as you have done with the while, with the for loop as it is presented here? Can you compute the sum of all the numbers from 0 to 100 using the for loop?

## The FOR loop

The format of a for loop is:
for(initializing expressions) { statements; // what the loop will do }

Prior to the for loop, declare a variable, such as an integer. This variable will be used for the three initializing conditions of the for loop: Telling the compiler at which value to begin Telling the compiler at which value to stop Incrementing or decrementing the loop (makes the loop move to the next value for code processing) Example: Counting from 0 to 10 // Counting From 0 To 10
count.cpp #include <iostream> using std::cout; using std::endl; int main() { // declare a variable int i; for(i= 0; i < 11; i++) cout << i << endl; return 0; } /* This opens the comment: This is the generated output: 0 1

## 2 3 4 5 6 7 8 9 10 */ This closes the comment

The letter i is the one I normally use when using an integer in a for loop but any other letter or variable name will work just as well. The reason that I like to use the i, is just from habit and seeing it most often used in textbooks for the for loop conditions. This makes for easier readability of my code. Using a longer variable name like number, seems a bit awkward in a for loop's condition statements:
for(number = 0; number < 11; number++)

just seems "cluttered with longer variable name". It is still a matter of preference and it would not have been wrong to declare int number instead of int i.
i= 0 told the compiler you are starting at 0. i < 11 told the compiler where to stop the loop i++ means i = i + 1 (which increments the loop,

## moves the loop to the next i

value. Counting backwards with a for Loop Tell the compiler where to start Tell the compiler when to stop Decrement the loop: j = j - 1 in its shorter form is j-countbackwards.cpp #include <iostream> using std::cout; using std::endl; int main(){ // declare a variable before starting int i; for(i=10; i > -1; i--) {

if(i == 0) cout << "Blast Off!" << endl; else cout << i << endl; } return 0; // return 0 indicates the end of the program }

The above loop starts counting backwards at 10; loop stops when the i value hits -1; Each step of the loop is decremented by -1, so after 10 is output, then 9 is output. If the i value hits 0, instead of printing 0 on the console, you will see the words "Blast Off!" [and end the line] because of the if/else statement. You can output a string to the console when the integer object has a zero value. It says, if i is 0, then print "Blast Off!", otherwise output i and end the line. You do not need to use the {} curly braces for the if statement or the else statement when only one statement is used. The for loop used the {} curly braces because that loop has more than one statement. Don't confuse conditions with the for loop statements. The conditions are inside the parentheses and tell how the loop will run and the statements outside the parentheses tell what the loop will do to the object types, in this case the integer object i Shortcuts for coding increments and decrements
j j k k m = = = = = j j k k m + + + 2 2 1 1 5

can be written j+=2; (adds 2 to the value of j) can be written j-=2; (substracts 2 from the value of j) can be written k++; (adds 1 to the value of k) can be written k--; (substracts 1 from the value of k can be written m+=5 (adds 5 to the value of m)

## Analyze This Loop:

int k; for (k = 0; k < 51; k +=10) cout << k << endl;

Review Exercise

At what value of k does the for loop begin? What is last value of k the for loop will output? By what value of k does the for loop increment each step? Write the output of the for loop. Write the output of the Following snippet of code:

int n; int stop = 3; int start = 8; cout << "start on 8" for(n = (start-1); n { if(n=stop) cout << "stop on else cout << "down to }

<< endl; >= stop; n--) " << n << endl; " << n << endl;

## Compiler Errors, Infinite Loops

Typical student errors in the for loop structure are not putting in the proper semicolon (;) after the first and second conditions, inside the parentheses or accidentally reversing the < or > symbols When a loop is counting forward, it makes sense that the loop should stop somewhere less than some value, or it will count forever an infinite loop. For example,
Count from 20 to 45 by 5's: int k = 0; for(k = 20; k < 50; k+=5) cout << k << endl;

Each number will be on a separate line because of the endl [end line] statement. cout << endl; is an empty line but cout << k << endl; is the output of the value of k, then a newline. Think of endl; as a line break. Nothing comes after it on that line so any other new output must be on another line. If by accident, a student had coded:

## for(k = 20; k > 50; k+=5)

where would the loop stop? It begins at 20, adds 5 so k=25, and next time k=30, then k=35 and when k=50 the stopping place is k "greater than" 50, so k gets 5 more added to it... forever. (This is called an infinite loop.) The way to stop an infinite loop varies between compilers. When I was using VC++ 6.0 on a Windows 98SE machine, I could stop an infinite loop by pressing the Break or Pause key but not all compilers work the same way to stop an infinite loop. N.B. When a for loop is incrementing (adding), make sure that the middle condition that stops the loop is NOT a > greater than symbol. Now consider a decrementing loop. Count from 50 to 20 by 5's:
int k; for(k=50; k>19; k--) cout << k << endl;

This code will count from 50 backwards by 5's and stop at 20 because the middle condition is k greater than (>) 19 for where the backwards counting should stop. So, when a for loop is decrementing (subtracting), make sure that the middle condition which stops the loop has NO < less than symbol, but a greater than > symbol, so that the loop will stop.

## The WHILE Loop

while1.cpp #include <iostream> int main(void) { int x = 0; int y = 0; cout << "Please enter an integer between 1 and 10: "; cin >> x; cout << "You entered: " << x << endl << endl; while ((x < 1) || (x > 10)) { cout << "Please enter an integer between 1 and 10: "; cin >> x;

cout << "You entered: " << x << endl << endl; if ((x < 1) || (x > 10)) { cout << "Your value for x is not between 1 and 10!" << endl; cout << "Please re-enter the number!" << endl << endl; } } cout << "Thank you for entering a valid number!" << endl; return 0; }

Note that since the condition is tested at the start, we have to prompt the user for a number before we start. Depending on the circumstance, we could arrange this loop in a more intelligent way. For instance, if we set the value of x to one that would make the loop execute as false the first time through, then it would work without gathering input before the loop. This is generally not a good idea though since we might have this code in a function and the variable in question might be an argument (more later on that if you don't understand it). A more accepted way of accomplishing our goal of laziness would be to use a sentinel. Usually a boolean (true or false) variable that we would set to false when the condition was not satisfied and set to true when it was. Then we can loop so long as our sentinel is false. Check it out.
while2.cpp #include <iostream>

int main(void) { int x = 0; int y = 0; bool validNumber = false; while (validNumber == false) { cout << "Please enter an integer between 1 and 10: "; cin >> x; cout << "You entered: " << x << endl << endl; if ((x < 1) || (x > 10)) { cout << "Your value for x is not between 1 and 10!" << endl; cout << "Please re-enter the number!" << endl << endl; } else validNumber = true; } cout << "Thank you for entering a valid number!" << endl; return 0; }

Strings
Using a string is easy. There are many ways to initialize it.
string s; string *ps = new string("Hiya!") ; const char sometext[]="A zero terminated string"; string ps=sometext;

A minor gotcha. Though string is in the <string> library, you can also access it via the std namespace, however cout may not work with it, as in this example below.
#include <iostream> using namespace std; int main(int argc, char* argv[]) { string str("Hello World!") ; cout << str << endl; }

The following code string1.cpp shows a number of ways to initialize a string. The s4 string uses one of the overloads of the constructor to copy from the start of a C string to the specified character. And s6 is initialized to a string with 80 asterisks.
#include <iostream> #include <string> using std::cout; using std::endl; using std::string; int main(int argc, char* argv[]) { string str("Hello World!"); cout << str << endl; string s2="A String"; char CString[]="A zero terminated C String"; string s3=CString; s3="Another string"; string s4(CString,&CString); string s5=s4.append(s2); string s51= s4 + s2; string s6(80,'*'); string s7=s5; string s8(s5); //Display each of the strings cout<<s2<<endl; cout<<s3<<endl; cout<<s4<<endl; cout<<s5<<endl;

## Working with C Strings

A C string is a zero terminated array of chars but the C++ string does without the extra terminating zero. Most likely it keeps track of the length internally but you should not make any assumptions about how the implementation works. Getting a C string into a C++ string is very easy. This code from string1.cpp does just that.
const char CString[]="A zero terminated C String"; string s3=CString; s3="Another string"; string s4(CString,&CString) ;

## Working with C++ Strings

A string can be anything up to a few gigabytes in size and is restricted by the available RAM. However for efficiency, the actual size is stored and the string is memory managed through the capacity() and reserve() functions. The current capacity of a string is given by capacity() and you can change it through reserve(). My experience is that reserve increases the capacity (if a larger value is used) but doesn't shrink it with a smaller value. Some compilers may actually shrink it but it isn't guaranteed. The actual length of the string can be less than the capacity but never more. To change the strings actual length, not its capacity use resize().

## Assigning and Appending Strings

Assignment can be done with = or the assign() member function. Both assign a constant string and can work with another string or a char * C String. However assign() can also take extra parameters for start and length.
const string s("Humpty Dumpty sat on a wall") ; string s1,s2,s3,s4; s1.assign(s,7,6) ; // Dumpty cout << "s1= " << s1 << endl; s2.assign("Once",2) ; cout << "s2= " << s2 << endl; s3="ZZY"; s3+= s1 += s2; cout << "s3= " << s3 << endl; s4="Once"; s4=s4.substr(2) ; cout << "s4= " << s4 << endl;

This outputs
s1= Dumpty s2= On s3= ZZYDumptyOn

It looks similar to substr() but with the difference that the second parameter of assign() is the length not the start position.
substr("once",2); // ce assign("once",2); // on

Emptying Strings
You can check if a string is empty with the empty() function. There is also a function clear() which empties a string, though it was never included in the library with Microsoft Visual C++ 6.0. (Not an oversight- just to do with the timing of including clear in the std library). You can however substitute erase() instead.

## Using String Functions - An Example

The example code string2.cpp demonstrates the following string functions find(), insert(), append() and replace() plus swap() for swapping this string with another, and substr() for getting part of a string.
#include <iostream> #include <string> using std::cout; using std::endl; using std::string; int main(int argc, char* argv[]) { const string s("Humpty Dumpty sat on a wall"); for (int i=0;i < s.length(); i++) { char c = s.at(i); cout << c << endl; } string s1(10000,' '); cout << "Length of s1 is now " << s1.size() << endl; cout << "Capacity of s1 is " << s1.capacity() << endl; s1.reserve(5000); cout << "Capacity of s1 is " << s1.capacity() << endl; s1.resize(500);

cout << "Capacity of s1 is " << s1.capacity() << endl; cout << "Length of s1 is now " << s1.size() << endl; if (s1.empty()) cout << "String is Empty" << endl; else cout << "String is Not Empty" << endl; s1.clear(); // if this doesn't compile use s1.erase(); if (s1.empty()) cout << "String is Empty" << endl; else cout << "String is Not Empty" << endl; string s2(s.substr(7,6)); const string s3=s.substr(); cout << "Humpty's 2nd name is " << s2 <<endl; cout << s3.npos << endl; cout << s3.max_size() << endl; s2.erase(); // Equiv of basic's right( string s9 = s.substr(s.size()-9,9); cout << "Last 9 chars of s is " << s9 << endl; // Find, insert, append and replace int atpos= s.find("Dumpty"); string starget = s; starget.insert(13," and Dumpty-The-Second"); cout << "New Story:" << starget << endl; starget.replace(7,6,"Duck"); cout << "Replaced Story:" << starget << endl; starget.append(" - the wall fell down. Poor build quality"); cout << "Appended Story:" << starget << endl; // Demo Swap string salpha ="alpha"; string sbeta ="beta"; salpha.swap( sbeta ); cout << "Alpha is now " << salpha<< endl; cout << "Beta is now " << sbeta << endl; return 0; } substr()

works with 0, 1 or 2 parameters as both parameters have defaults. The equivalent of the Basic string functions Left(), Mid() and Right() are : Left(string,len) - substr(0,len) Mid(string,startpos,len) - substr(startpos,len) Right(string,len) - substr( size()-startpos+1, len) The max_size() function returns the longest string possible, just less than the static const value string::npos that is returned if a call to find() fails. npos is the unsigned equivalent of -1. This is a magic number that's always returned for failed searches. It will always be bigger than max_size().

About string2.cpp The first loop indexes a string with the at() function. Then s1 is created as a 10000 long string of spaces. Both reserve() and resize() affect the capacity() before erasing the string and checking if it's empty by calling empty() Then it uses strings s3, starget and s9 to demonstrate string substitution with insert(), replace() and append(). Finally swap() is used to swap two strings. The max_size() function returns the maximum size of a string. Note: Don't do a find() and compare the result with -1. Always compare string::npos instead. This code below is bad.
int result = s.find("text") ; if (result == -1)
...

This is better.
if (result == string::npos) ...

Comparing Strings
Just use == with strings, as if you were comparing two ints. Behind the scenes, the main comparison operator == is defined as
bool operator == (const string& left, const string right) ;

## but a comparison like

if (str =="Hello")

could be quite inefficient with this definition because it would have to first convert the char * parameter right to a temporary string object and then copy the value into it. Thankfully there are two overloads which implement a comparison of a string and char * or a char * and string, just to avoid this inefficiency.

## The compare function provides more flexibility

This is another overloaded function that allows comparison between parts of strings and char * or other strings. This code below is string3.cpp which demonstrates the compare() function.
#include <iostream> #include <string> using std::cout; using std::endl; using std::string;

int main(int argc, char* argv[]) { const string s("Humpty Dumpty sat on a wall"); string s1,s2,s3,s4; s1.assign(s,7,6); // Dumpty cout << "s1= " << s1 << endl; s2.assign("Once",2); cout << "s2= " << s2 << endl; s3="ZZY"; s3+= s1 += s2; cout << "s3= " << s3 << endl; s4="Once"; s4=s4.substr(2); cout << "s4= " << s4 << endl; if ( s.compare(14,3,"sat",0,3) ==0 ) cout << "Strings Match" << endl; else cout << "Strings Don't Match" << endl; system("Pause"); return 0; }

This compares the part of s that starts at position 14 and is 3 chars long with the part of "sat" that starts at position 0 and is also 3 chars long (i.e. "sat") and returns 0 if they match. Don't forget the ==0 or your logic will be inverted and wrong!

Implementing Simple IO
simpleio.cpp

## #include <iostream> int

main() { std::cout << "I am writing out to the screen" << std::endl; std::cout << "Look ma it's on another line..." << std::endl int var = 3; std::cout << "I'm now outputting the variable var: " << var << std::endl;

return 0;
}

## Try running the above piece of code. Does it work as expected?

What did you do to fix it? Step through the above code after fixing any erroneous mistakes on my part to see what it does. cout is a function in a library that allows us to write to the console screen. The << is an operator which allows streaming. We stream whatever is on the right into whatever is on the left. The cout function is accessed using the iostream library. Therefore, if we want to use this function (as well as a whole bunch of other rather useful functions) we can include this library into our project. This is true for any type of code that another programmer has made and put into a library. We simply include the library headers and use to our hearts content without ever knowing how it works. Basically you interpret the above lines by stating whatever is on the right is set on the output stream. You can also send variables to the screen as I have shown above. Try seeing if you can output messages of your own, and also any other types that you may have been exposed to so far. Does it work for all the types that you have been using until now?