This post is a continuation of the previous topic, with a different program. In the following program, a constructor and destructor are used; they are included by default whenever a class is working inside a program. The constructor essentially "creates" the class' objects as they are declared, and when main ends, the destruct or "destroys" any created objects to free memory locations that the objects used so the memory can be used by another program. In many programs involving classes, a destructor or constructor doesn't need to be declared, but if main relies on several classes and many objects for each class, they can come in handy for tracking how many objects are created during the program's run. Either can also output a message upon creation or destruction of a class object (as the destructor does below). The constructor always executes at the moment a new class object is declared, and the destructor executes prior to ending the program, before return 0; executes.
And the output:
(yes, that is my terminal... ^^")
Showing posts with label functions. Show all posts
Showing posts with label functions. Show all posts
Friday, March 27, 2015
Tuesday, March 24, 2015
Post #14 - first look at classes/objects
Lot of catching up to do here, eheh... Here's a simple demonstration of a class. A class is like a function inside of a function, it makes your code very condensed so more work is put into the general goal/purpose of the program rather than in what each function or variable is doing in the background. The background work is handled by the class's member functions. I like to think of it as a kind of castle or house - outside of the castle, there is public property and anyone can access whatever things lay outside the castle walls. However, anything inside the castle is private property, and only the members of the castle can access these things. Friends of the castle inhabitants must ask them first if they can use anything inside the castle, and cannot access things inside the castle directly without permission from the members. In program terms, a class has two permission groups - public and private. Variables and functions can be inside either group, but private variables and functions can only be accessed through the class's public member functions. The private group has content only known to the class, and this content (variables, functions, etc) can't be accessed without a call to a public member function that handles that content.
In the programming example above, Queen()and King() are member functions of class KINGDOM. They are public, meaning that outsiders know of their presence and that the royalty can communicate with others outside of the Castle, the object that is called with its member functions before main. However the castle's treasure of gold and silver is private - it's safe to keep your valuables hidden, after all. The queen knows how much silver and gold is stored away (5 kg and 9.9 kg), and assigns these numbers to their respective private variables. The king uses the same variables to tell the rest of the "public" (i.e. the rest of the program not part of the Castle object) how much of each the castle has. However, the amount of each within the castle cannot be modified by outsiders once their amounts are set, because they are stored as private, not public. If the values needed to be changed, a new member function would have to be created to re-assign new values to silver and gold, the queen can initialize them with different values, or the queen can be passed values set by the main program since Queen() is a public function of the class (via initialization, user input, or data read-in).
The resulting output is as follows:
Kingdom treasury:
Silver = 5 kg
Gold = 9.9 kg
Using classes and objects can obviously neat-ify programs, and tracing exactly who does what at a specific point in main is made easier by public member functions that can access private variables so their data isn't altered inadvertently by main.
In the programming example above, Queen()and King() are member functions of class KINGDOM. They are public, meaning that outsiders know of their presence and that the royalty can communicate with others outside of the Castle, the object that is called with its member functions before main. However the castle's treasure of gold and silver is private - it's safe to keep your valuables hidden, after all. The queen knows how much silver and gold is stored away (5 kg and 9.9 kg), and assigns these numbers to their respective private variables. The king uses the same variables to tell the rest of the "public" (i.e. the rest of the program not part of the Castle object) how much of each the castle has. However, the amount of each within the castle cannot be modified by outsiders once their amounts are set, because they are stored as private, not public. If the values needed to be changed, a new member function would have to be created to re-assign new values to silver and gold, the queen can initialize them with different values, or the queen can be passed values set by the main program since Queen() is a public function of the class (via initialization, user input, or data read-in).
The resulting output is as follows:
Kingdom treasury:
Silver = 5 kg
Gold = 9.9 kg
Tuesday, March 17, 2015
Post #12 - recursive function
Jumping a bit to recursive functions here.
What's a recursive function? It's a function that calls itself from within its own declaration.
For example the recursive function below calls itself twice in the 4th line of the function body.
Once the if statement becomes true, return 4 is there as a termination to any function call made to it (because calling functions forever in a program takes up memory). The two function calls each decrement the initial integer passed to them, a, by 1 and by 2.
If a = 3, the function call would immediately return 4 and the rest of the body would not execute. For numbers > 3, such as 4, the else statement goes into effect and returns a + the function call to H(a - 1)+ call to H(a - 2); or 4 + H(3) + H(2). H(3)and H(2) both trigger the if statement at the beginning of the function, and they both return 4. So the returning integer if 4 was entered is 4 + 4 + 4, or 12.
int H(int a)
{
if(a <= 3)
return 4;
else
return a + H(a - 1) + H(a - 2);
}
What's a recursive function? It's a function that calls itself from within its own declaration.
For example the recursive function below calls itself twice in the 4th line of the function body.
Once the if statement becomes true, return 4 is there as a termination to any function call made to it (because calling functions forever in a program takes up memory). The two function calls each decrement the initial integer passed to them, a, by 1 and by 2.
If a = 3, the function call would immediately return 4 and the rest of the body would not execute. For numbers > 3, such as 4, the else statement goes into effect and returns a + the function call to H(a - 1)+ call to H(a - 2); or 4 + H(3) + H(2). H(3)and H(2) both trigger the if statement at the beginning of the function, and they both return 4. So the returning integer if 4 was entered is 4 + 4 + 4, or 12.
int H(int a)
{
if(a <= 3)
return 4;
else
return a + H(a - 1) + H(a - 2);
}
Sunday, March 15, 2015
Post #11 - function templates
Function templates use the same function to accept multiple types of data without having to recreate the function again for each needed data type. Overloaded functions share the same name but have different parameter lists for each one, and can work with different data while making different function names in the program easy to remember.
An overloaded function prototype:
void ShowBook(int array[]);
void ShowBook(string, float);
ShowBook needs to have two calls to it in main that have a different number of variables in the parentheses, otherwise one will be called twice and passed an incompatible data type or the wrong number of arguments.
cout << "Chapters of book: " << ShowBook(volume);
cout << "Title and price of book: " << ShowBook(title, price);
The function definitions for each are considered as two separate functions.
void ShowBook(int v[])
{ //body of function }
void ShowBook(string t, float p)
{ //body of function }
A function template can cause a function to be able to work with any data type passed to it in main, if the header template <class name> is put above the function call and function definition to define the created typeholder name, which is not a new data type but acts as a container to accept any data type. name can be anything you want to name the typeholder, typically T or type is used to prevent confusion though. It goes before the variable passed to the function whose data type could become several different types over the run of the program.
template <class money>
int BookPrice(money books);
books can now accept any type given by main:
int volume1 = 5;
float volume2 = 3.99;
cout << "Price in dollars: $" << BookPrice(volume1);
cout << "Price in dollars & cents: $" << BookPrice(volume2);
The function definition should also have the template class put before it as well, otherwise the reference to money as a typeholder will not be understood by the compiler.
An overloaded function prototype:
void ShowBook(int array[]);
void ShowBook(string, float);
ShowBook needs to have two calls to it in main that have a different number of variables in the parentheses, otherwise one will be called twice and passed an incompatible data type or the wrong number of arguments.
cout << "Chapters of book: " << ShowBook(volume);
cout << "Title and price of book: " << ShowBook(title, price);
The function definitions for each are considered as two separate functions.
void ShowBook(int v[])
{ //body of function }
void ShowBook(string t, float p)
{ //body of function }
A function template can cause a function to be able to work with any data type passed to it in main, if the header template <class name> is put above the function call and function definition to define the created typeholder name, which is not a new data type but acts as a container to accept any data type. name can be anything you want to name the typeholder, typically T or type is used to prevent confusion though. It goes before the variable passed to the function whose data type could become several different types over the run of the program.
template <class money>
int BookPrice(money books);
books can now accept any type given by main:
int volume1 = 5;
float volume2 = 3.99;
cout << "Price in dollars: $" << BookPrice(volume1);
cout << "Price in dollars & cents: $" << BookPrice(volume2);
The function definition should also have the template class put before it as well, otherwise the reference to money as a typeholder will not be understood by the compiler.
Post #10 - max 'n' min
By the way, happy 3.14 day.
Is there a program that can calculate pi to xx number of digits? Haven't heard of one yet...
Recently I came across some old newbie-code I had done to determine min and max between two inputted numbers. It wasn't very fancy, and I was initially stumped as to why it kept assigning the wrong numbers to min and max, only to realize it was me who was labeling the maximum/minimum wrong in the strings. go figure.
Thankfully, it's easier to find the max and min of any number within a given array (suppose the size = N). The logic flows like this: going through each number in the array, check the number (using if) to confirm if it is greater than the starting number, array[0], if so then the max number is the number at position array[a]. Next check the same number (using if) to confirm if it is less than min (which is also assigned array[0]), if so the min number is the position at array[a]. If neither condition passes, the loop moves on to the next number in the array.
For instance if the array was: int array[N] = {5, 9, 2, 6, 10, 1} and N = 5;
int max = array[0];
int min = array[0];
The loop would assign max and min as follows:
iteration 0
5 (array[0]) larger than max (array[0])? 5 !> 5, so max = array[0].
5 (array[0]) smaller than min (array[0])? 5 !< 5, so min = array[0].
iteration 1
9 (array[1]) larger than max (array[0])? 9 > 5, so max is now assigned array[1].
9 (array[1]) smaller than min (array[0])? 9 !< 5, so min remains as array[0].
iteration 2
2 !> 9, max = array[1].
2 < 5, min is now assigned array[2].
iteration 3
6 !> 9, max = array[1].
6 !< 2, min = array[2].
iteration 4
10 > 9, max is now assigned array[4].
10 !< 2, min = array[2].
iteration 5
1 !> 10, max = array[4].
1 < 10, min is now assigned array[5].
So the maximum integer is 10, and minimum integer is now 1.
Note that max and min are passed by reference & so the function can directly modify their contents using the loop. This is a kinda roundabout way to return two different variables from a function without using return, if the two variables are introduced in the main program before calling the function, as return can only return one variable per function.
Is there a program that can calculate pi to xx number of digits? Haven't heard of one yet...
Recently I came across some old newbie-code I had done to determine min and max between two inputted numbers. It wasn't very fancy, and I was initially stumped as to why it kept assigning the wrong numbers to min and max, only to realize it was me who was labeling the maximum/minimum wrong in the strings. go figure.
Thankfully, it's easier to find the max and min of any number within a given array (suppose the size = N). The logic flows like this: going through each number in the array, check the number (using if) to confirm if it is greater than the starting number, array[0], if so then the max number is the number at position array[a]. Next check the same number (using if) to confirm if it is less than min (which is also assigned array[0]), if so the min number is the position at array[a]. If neither condition passes, the loop moves on to the next number in the array.
For instance if the array was: int array[N] = {5, 9, 2, 6, 10, 1} and N = 5;
int max = array[0];
int min = array[0];
The loop would assign max and min as follows:
iteration 0
5 (array[0]) larger than max (array[0])? 5 !> 5, so max = array[0].
5 (array[0]) smaller than min (array[0])? 5 !< 5, so min = array[0].
iteration 1
9 (array[1]) larger than max (array[0])? 9 > 5, so max is now assigned array[1].
9 (array[1]) smaller than min (array[0])? 9 !< 5, so min remains as array[0].
iteration 2
2 !> 9, max = array[1].
2 < 5, min is now assigned array[2].
iteration 3
6 !> 9, max = array[1].
6 !< 2, min = array[2].
iteration 4
10 > 9, max is now assigned array[4].
10 !< 2, min = array[2].
iteration 5
1 !> 10, max = array[4].
1 < 10, min is now assigned array[5].
So the maximum integer is 10, and minimum integer is now 1.
Note that max and min are passed by reference & so the function can directly modify their contents using the loop. This is a kinda roundabout way to return two different variables from a function without using return, if the two variables are introduced in the main program before calling the function, as return can only return one variable per function.
Saturday, March 7, 2015
Post #6 - Random numbers
I usually end up being behind a post if I have homework or other life stuff going on that needs to get done, so here's a program that was going to be posted yesterday.
Using the libraries cstdlib for the srand() and rand() functions, and ctime for the time() function, the program displays a random year within the range 1985 - 2015. The range limit is achieved by setting the random year to display equal to the remainder of the randomly generated number divided by 31, resulting in an integer between 0 and 30 (the computer counts starting from 0, not starting from 1, so in our counting style 0-30 would be 1-31).
We want the difference of the years (2015 - 1985 = 30) plus the starting year (1985) to be the range of the random year, but if 30 was used as the divisor, the range would be one year off from 2015 (since in computer numbers, (0 + 29) = 1-30, it would count from (0 + 1985) to (29 + 1985) which is 1985 - 2014). The off-by-one error can be fixed, because another 1 was not added to 30 to account for 2015 as one of the years, just change 30 to 31, thus raising the range to 1-31 and including 2015 in the computer's random years selection.
This sounds confusing but try reading the 0 of the modulus (%) results as a 1, and adding 1 to every integer in the range including the last number. This kinda converts it to human-range starting with 1, and to convert back, subtract 1 from every number for counting from 0.
Here's the output:
This program randomly chooses a year between 1985 and 2015.
The random year is 1985
Using the libraries cstdlib for the srand() and rand() functions, and ctime for the time() function, the program displays a random year within the range 1985 - 2015. The range limit is achieved by setting the random year to display equal to the remainder of the randomly generated number divided by 31, resulting in an integer between 0 and 30 (the computer counts starting from 0, not starting from 1, so in our counting style 0-30 would be 1-31).
We want the difference of the years (2015 - 1985 = 30) plus the starting year (1985) to be the range of the random year, but if 30 was used as the divisor, the range would be one year off from 2015 (since in computer numbers, (0 + 29) = 1-30, it would count from (0 + 1985) to (29 + 1985) which is 1985 - 2014). The off-by-one error can be fixed, because another 1 was not added to 30 to account for 2015 as one of the years, just change 30 to 31, thus raising the range to 1-31 and including 2015 in the computer's random years selection.
This sounds confusing but try reading the 0 of the modulus (%) results as a 1, and adding 1 to every integer in the range including the last number. This kinda converts it to human-range starting with 1, and to convert back, subtract 1 from every number for counting from 0.
Here's the output:
This program randomly chooses a year between 1985 and 2015.
The random year is 1985
This program randomly chooses a year between 1985 and 2015.
The random year is 2000
This program randomly chooses a year between 1985 and 2015.
The random year is 2015
After re-running this one for a while, 2015 finally appeared (1/30% chance...) (thought something was wrong with my logic for a sec. turns out it just needed more chances to occur).
The off-by-one is easy to miss, so when in doubt, know that the computer almost always starts counting from 0 and a simple overlooked thing like adding 1 can cause the range to fall into place correctly.
Wednesday, March 4, 2015
Post #4 - Functions!
Functions are quite fun (they do require getting used to remembering the prototype and function call, as well as the function itself) because they can drastically reduce the main section of a program to just a few statements, as the function calls do the work instead of the main program, allowing you to focus on other things in the program besides something simple like user input or output display. Functions also can help narrow down to one function's elements or operations instead of looking through the entire program for what caused the glitch.
An example - here is the program from before, except now everything is condensed into 3 functions corresponding to the 3 tasks of the program - (1) prompt for input, (2) display the input, (3) ask user to continue. Everything looks neater and easier to read! ^_^
Of course, for functions to work they need three presences in the program.
void UserInfo(string& a, string& b, string& c)
{
cout << "Enter your name: ";
getline(cin, a);
cout << "Enter your city: ";
getline(cin, b);
cout << "Enter your country: ";
getline(cin, c);
//Function call to DisplayInfo inside of function UserInfo
DisplayInfo(a, b, c);
}
An example - here is the program from before, except now everything is condensed into 3 functions corresponding to the 3 tasks of the program - (1) prompt for input, (2) display the input, (3) ask user to continue. Everything looks neater and easier to read! ^_^
Of course, for functions to work they need three presences in the program.
- The function prototype is seen by the compiler before main. It include the datatype the function will return to main (if no type is returned, void is used instead), the name of the function, and the datatypes of the variables the function will be receiving from main. The names do not have to match those within main and can be omitted, since it is the simplified form of the actual function which is added later. If the prototype is omitted, the compiler will not match the function call with the function definition, and will see the function call as undeclared and the program will not work.
- The function call is the only part of the function appearing in the program. Since its datatypes of its variables and its return type are already defined by the function definition and the prototype, they should not be included in the function call (over-definition). The variables passed to the function must use the names given in main, because the function will use the values in main for computations or to set values for them. Obviously these are necessary, without a function call your function doesn't do anything!
- The function definition comes either before or after main and is the primary body of the function. Here all the work the function does is clearly defined, and any result to be sent back to main is returned with return. If a result is expected to be returned, main should have a variable ready to store the returned result, or a cout statement displaying it in main. A function of type void can be displayed with cout but should not be assigned to a variable, since it is not a variable type. void is best used for functions that only assign or display values and do not do computations, like Display()or Input().
Following these three guidelines it's easy to write custom functions for a variety of computations. Functions can even be put inside other functions or called using a function (the latter does not work with void functions). In the above example, DisplayInfo could be put inside of UserInfo because they use the same strings as parameters and only differ in handling of the strings - one stores input while the other displays it.
void UserInfo(string& a, string& b, string& c)
{
cout << "Enter your name: ";
getline(cin, a);
cout << "Enter your city: ";
getline(cin, b);
cout << "Enter your country: ";
getline(cin, c);
//Function call to DisplayInfo inside of function UserInfo
DisplayInfo(a, b, c);
}
//DisplayInfo keeps its original code below, but can be omitted in main above since it is called here instead.
A note about & (passing by reference):
If & (ampersand) is placed at the end of the datatype, the variable can be externally modified by the function, a copy of the variable's location is not passed to the function as it is in passing by value (without a &). This shows why each string with & had its contents changed when data was input into each one using UserInfo(), the ampersand allowed data to be input directly into the strings passed from main, and they were then passed by value to DisplayInfo(), which displayed a copy of the strings (since it did not need to modify them). If no ampersand was included in the first function, DisplayInfo() would have been passed blank values, because passing by value does not change the values of the strings in main but the values of a copy of each string, which are held in different locations than those in main. In my opinion, if the values are going to be changed and used in main again, it's better to pass by reference to assign them their new values, and then pass them by value to not change what they were set to by the first function.
Subscribe to:
Posts (Atom)