L34rn teh C++ Lesson 5

Cunbelin

Newbie
Joined
Aug 3, 2003
Messages
281
Reaction score
0
Alright well time for Lesson 5



Lesson 5

MI BRANE STOPD WORKNG AN OWR AGO



Ok a change of pace from functions to start, and then we'll tackle bit more about functions. Ok so remember when I mentioned the goto, and how it was used for functions, well there was another way to use it, and that was to send it to a line that had a conditional, and then have the program run through until it hit the orignal goto statement, that sent it back to the conditional. We'd have a bit of code that kept on looping through as long as a conditional was true. Lets take a quick look at some psuedo code that describes this:



if(this is true)

{

do something

goto the if statement

}



so as long as the if statement gets a true, we will keep on doing something over and over again. Now this doesn't do us much good because we do it over and over again, so what we have to do is modify what is being tested so that we eventually exit the loop. When a loop is stuck in a state of never being able to exit we call it an infinite loop. Anyway we don't want to use the goto so we need something else, in this case there are two options, recursion, or a loop statement. For now we are going to use a loop statement, as they are simpler to understand. There are three kinds of loops in C++



The first is called a while loop, a while loop works exactly like our example above, in fact if you have an if statement you can replace it with a while and it will work without any questions. Here is an example of a While loop:



PHP:
#include <iostream.h>

int main()
{
	int an_int = 7; //OMG WTF a declaration and a definition!
	while(an_int >= 0 )//so this should go until an int is greater than or equal to 0
	{
		cout << an_int; //old hat
		cout << "\n"; //seen that too
		an_int--; //OMG! WHUT IZ DAT!
	}
	return 0;
}

Ok a few new thing snuck in there too, but as you can see we could just as easily put if or while there, the results would be very different though. You should also note that we modify the variable we are testing if we didn't we would be stuck in an infinite loop. How did we modify it ? with the line an_int--; of course, there are some more operators I want to introduce with loops, these are called the increment and decrement operators, they both come in two variations, postfix and prefix, we used a postfix decrement operator to make an_int 1 smaller. The increment works just like this but with ++ (get it, there was C then there was C++), both operators are the equivalent to writing an_int -= 1; or an_int += 1; for increment. The difference between postfix and prefix is a little harder to understand, for prefix, to show this lets take a look at another example of code:

PHP:
#include <iostream.h>

int main()
{
	int an_int = 7;
	int another_int = 7;
	while(an_int >= 0 )
	{
		cout << an_int--; //postfix decrement
		cout << "\t"; //cheetz he uzez new escape character! this just puts a tab in
		cout << --another_int; //prefix decrement
		cout << "\n";
	}
	return 0;
}

Alright so if you didn't notice the difference is that the prefix evaluates before cout is used, and postfix evaluates after cout is called. Using pre, and postfix is pretty much only a choice, you can always just put cout on the line after the postfix instead of using prefix, and generally you will see postfix over prefix. Ok so now that we have those new operators out of the way lets talk about what I did on the first line of main, you can streamline your variables by defining them at the time of declaration, you can't use any other operators on them except the =, there is actually a second way to do this instead of using an = sign you can use parentheses, like this:
int an_int(7);
that gets the same result as the code I used above.

Time for the "For loop". The For loop is a little more streamlined than the while loop, it has some features built into it, also it is another syntactical oddity, like the switch statement, lets take a look at one:
PHP:
#include <iostream.h>

int main()
{
	int an_int;
	for(an_int = 0; an_int <= 7; an_int++) //the first one makes an_int equal zero
                 //The second is the test
                 //The third is a statement executed each time through
	{					
		cout << an_int; //old hat
		cout << "\n"; //old again
	}
	cout << an_int;
	return 0;
}

There we go a little simpler than the while loop, we integrate three statements into the parentheses, the first one is to initialize variables, you can add more than one initialization here by using comma's to separate them:
for(an_int = 0, another_int = 0; an_int != 3; an_int++, another_int++)
The second element is the test, as long as that evaluates as true you will go through the loop, you can only have a single test as it MUST evaluate to a single value. The third one is a statement to execute every time you go through the loop, you can also add multiple statements to the loop like what was done above. To note here is the sequence of a for loop:
intialize
test
execute block code
execute statement
if the test fails you will still execute the statements but the block code will be ignored. This means as in the above example the cout outside of the loop shows an_int, being 8 not 7. Generally it is good practice to only use operators in the for loop but you can put any statements you like in there like this:
PHP:
int main()
{
	int an_int;
	for(an_int = 0; an_int <= 7; ++an_int, cout << an_int)	//the code is shorter
                //but it is not as clearly readable
                //and so you should probably stick to operators
	{							
		cout << "\n";
	}
	return 0;
}

There is one more kind of loop, it is called the do/while loop, the do while loop is used to simplify your code, it allows you to run through your loop code once before testing. You will actually use this on occasion, here is the format for it:
PHP:
#include <iostream.h>

int main()
{
	int an_int = 7;
	int another_int = 0;
	do
	{
		cout << an_int--; //postfix decrement
		cout << "\t";
		cout << another_int++; //prefix decrement
		cout << "\n";
	}while(an_int >= 0 && another_int <= 7); //OMG what is this two tests!
	return 0;
}
Basically it is the exact same as a while loop except that the test is skipped on the first time through, after that it works exactly like a while loop. Now I threw something else in here, a way to do two tests, we are using an operator called the and operator, so that line reads, "while an_int is greater than or equal to 0 AND another_int is less than or equal to 7". We could also use the or(||) operator (just replace and with or) if we only cared if one of them works.

Ok that is enough on loops, we will be using a loop to make our calculator work a bit more like a real application. We are now going to turn back to functions for a little bit. I want to talk a little bit about what a function should be first, functions are meant to break a problem down into simpler parts, the idea is kind of like building something, lets say a pyramid, we have alot of foundation blocks at the bottom, these are little small functions that do simple things, then we build on it with fewer blocks these draw from the small functions to be more complex, then we continue on until finally we get to the apex, the main function, the starting point for our application. This is how your programs should be designed, another thing to keep in mind is that functions shouldn't be multipurpose, as an example I have a multipurpose tool on my keys, it has 10 tools or something in it, unfortunately none of them are very good at what they do compared to the real tool. We want our functions to be real tools, tools that do their work well.

Alright time to learn a new feature of functions, the defaulted argument. Sometimes we find that there is an argument that we have to add, that 99% of the time is the same, we still need it for those times when it is different, but most of the time we don't, so we use what is called a defaulted argument. This means that unless we put in a specific argument, the function assumes we want the defaulted argument. Heres a couple of rules about defaulted arguments, first they have to come after the non-default arguments, second if you have more than one defaulted argument you can't pick and choose which one you want non-defaulted. Alright lets take a look:
PHP:
int funA (int a, int b = 5, int c);  //NO can't do that
//everything after B must be a defaulted!
int funB (int a, int b = 5, int c = 3);  //YES this works fine
//but if we want to put a non defaulted argument in c
//we have to supply an argument for b as well

Now the rule is that if we default arguments on declaration they must match exactly with the arguments on definition. Alright time to make that calculator more useful, first thing we are going to do is add a loop so that we keep on asking to do problems until the user tells us they are done, second thing is we are going to add division in but we have to add an error check to avoid divide by zeros. Also because we don't want to prompt the user for numbers if they just want to quit, I inserted the prompts for that back into the cases. (we could have added an if statement as well but we will work out an even better option soon)
********************continued on next post*********************
 
From the first post:
PHP:
#include <iostream.h>

int add (int first, int second);//we need two numbers here so that we can do our work
int subtract (int first, int second);//to do two arguments we seperate them with a comma
int multiply (int first, int second);
int divide (int first, int second);


int main ()
{
	int first_number; //here is where we put the first number input
	int second_number; //the second number goes here
	char option = 'a'; //this will hold what option the user choses and be the test for the loop
        while(option != 'q') //we previously tested interatively in our loops now we are using a flag
        {
            // a little nicer to present the menu this way
            cout << "Please choose a mode:";
            cout << "\n[+]addition\n[-]subtraction\n[*]multiplication\n[/]division\n[Q]uit\n>"; 
            cin >> option;
            switch(option)
            {
                    case '+':
                    {
                            cout << "Please enter the first number\n>";
                            cin >> first_number;
                            cout << "Please enter the second number\n>";
                            cin >> second_number;
                            cout << add(first_number, second_number);
                            cout << "\n";
                            break;
                    }
                    case '-':
                    {
                            cout << "Please enter the first number\n>";
                            cin >> first_number;
                            cout << "Please enter the second number\n>";
                            cin >> second_number;
                            cout << subtract(first_number, second_number);
                            cout << "\n";
                            break;
                    }
                    case '*':
                    {
                            cout << "Please enter the first number\n>";
                            cin >> first_number;
                            cout << "Please enter the second number\n>";
                            cin >> second_number;
                            cout << multiply(first_number, second_number);
                            cout << "\n";
                            break;
                    }
                    case '/':
                    {
                        
                            cout << "Please enter the first number\n>";
                            cin >> first_number;
                            cout << "Please enter the second number\n>";
                            cin >> second_number;
                            cout << divide(first_number, second_number);
                            cout << "\n";
                            break;
                    }
                    case 'Q':
		    {
			option = 'q'; //if they used a big Q set it to a little one
                    }
                    case 'q':
                    {
                        break; //if it is already a little q all we have to do is break to the while test
                    }
                    default :
                    {
                            cout << "You didn't enter a +, -, *, /, or Q";
                            cout << "\n";
                            break;
                    }
            }
        }
	return 0;
}

int add (int first, int second)
{
	return (first + second);
}

int subtract (int first, int second)
{
	return (first - second);
}

int multiply (int first, int second)
{
	return (first * second);
}

int divide (int first, int second)
{
    if(second == 0) //if the second one is equal to 0 we can't do it so
    {
        cout << "Error Divide By Zero!"; //we print an error
        return 0; //and return zero, not ideal but we will fix it soon.
    }
    else
    {
        return (first / second); //if isn't a zero then go to it
    }
}

Well there we go finally what I'd call a real application, and now that you have that I want to introduce you to real testing, it is all well and good to write something that should work, but you need to test it to make sure it does, not just the debugger or compiler, we need to test our logic. As silly as it is you need to go through and try all possible options here, that means you need to select all our operators, and test them, you need to make sure zero checking works, and be sure it works when you hit a non-option. Alright enough for today, we are going to refine this further tomorrow using mostly things we already know, and we'll introduce pointers and references as well.
 
nice calculator ;) i hope you don't mind if i comment on two things?

maybe some guys already realized that the division only gives int numbers. 5/2 = 2 (?)

wanna fix that?

use:
PHP:
float divide (float first, float second);
in both lines instead of:
PHP:
int divide (int first, int second);

i hope you still know what "float" is?`don't disappoint Cunbelin now ;).
and maybe you guys want to give the user the chance to correct his input in the division in case he typed something like <=0 as second number? so check what kinda viariable the user typed in when the programm is still in the case: '/' part. either try it youself or read on ;)


PHP:
case '/':
			{
				cout<<"Please enter the first number: ";
				cin>>first_number; //inpuit: first number
				cout<<"\nPlease enter the second number: ";
				cin>>second_number; //inpuit: second number
					if(second_number <= 0) //check which number was typed in. is it equal or smaller than zero?
					{
						cout<<"Please enter a valid number  ";//too small...
						cin>>second_number;//try again
					}
				cout<<divide(first_number, second_number)<<endl;//seems to be ok.. go on
				break;
			}

//and now you can use:

//divide
float divide(float first, float second)
{
	return (first / second);
}

<edit>" endl (end line) " is the same as " \n ", so it doesn't really matter which one u use.</edit>
 
Dear god Echelon, think on the green!
The GREEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE*ARK*UFF*...

/me collapses from lack of oxygen
 
yeah thats a pretty cool calculator. you should add variable parameter lengths for the operator functions so you can add and multiply in succession. Adding the memory var would also be cool so you can set and recall a number
 
sorry this is a late message,

but for division of ints you could also use
(first/second) + (first%second)
although its a little more fuzzy :|

I cant remember, when you divide a float by a float, will you get the remainder(the decimals) when you return (first/second)? or do you still have to use %?
 
Originally posted by Orange
sorry this is a late message,

but for division of ints you could also use
(first/second) + (first%second)
although its a little more fuzzy :|

ARUGH?!
Let's try 5 divided 3 with your method...

In integer math...
(5 / 3) + (5 % 3) = 2 + 2 = 4 -- wrong

In float math...
(5 / 3) + (5 % 3) = 2.5 + 2.0 = 4.5 -- wrong

Either you're on crack, or I dont understand what you're trying to say.
 
Originally posted by Sandman
In integer math...
(5 / 3) + (5 % 3) = 2 + 2 = 4 -- wrong

In integer math...
(5 / 3) + (5 % 3) = 1 + 2 = 3 -- correct :cheese:
 
You sure? Me go write crappy program real quick to check myself :-p

edit: Okay, okay. You're right. 5/3 in integer math is 1. But the method still won't give you the right answer!

Note to self: do error checking before posting embarrassing mistakes in coder-central :eek:
 
Back
Top