Friday, March 27, 2015

Post #15 - more classes/objects

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... ^^")

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.

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);
}

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.

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.

Thursday, March 12, 2015

Post #7 - arrays and sentences

I realized that I had skipped number 7 in the post count...
Here's an example of a sentence array (to continue from post #9).


In this snippet, the array holding the sentence is not actually defined - because the sentence is actually an array of characters in itself. When the user enters a sentence, getline() stores the sentence into a string of characters and spaces. This by itself is not an array though, because to work with it the size of the array needs to be found. The .length() member function for strings can be used for this purpose, the length of the sentence string becomes the length of the character array. As getline() includes the \n from the user's [Enter] input, 1 must be subtracted to avoid having .length() count that extra character as part of the sentence. Now that we have the size of the sentence in characters, we can use a while loop with an increment integer or a for loop to step through the sentence and keep track of how many uppercase, lowercase and vowels are in the sentence for the user. The first two rely on two functions from <cctype> library to check for upper or lower case characters. Note that sentence, while treated as a string for the user to initialize before the while loop, is now treated as a character array within the loop simply by including the increment variable in brackets after the string name. Now sentence is called as sentence[check] and each character of the string is checked for each of the three conditions. Once one of them has been met or none of them match (i.e. the sentence has a space at that position), the check increments and goes to the next character in the sentence.

Post #9 - using an array

Today I'll introduce arrays. Arrays are sections of consecutive memory spaces that can hold variables of the same data type in order. They can hold any of the main data types (int, float, double, char, string), and are especially helpful in stepping through strings and sentences (a sentence is basically an array of characters with a \0 at the end, including punctuation and upper/lower chars). When an array is declared, the compiler reserves memory space for the size of the array specified in the brackets [].

int arrayOfIntegers[9];

The array above is named "arrayOfIntegers" (although when naming arrays the same naming style should be used as you name variables and functions, they don't have to be this obvious!). Because the int datatype is used, it only holds integer numbers. The brackets to the right of the array name specify the exact size of the array. However, since an array always counts from 0, arrayOfIntegers actually holds 0-8 integers. (the array counting scheme is from array[0] to array[n - 1], and n is the number of total items held by the array)

Data can be entered into the array via three ways - the array can be initialized when it is declared, the user can enter numbers into the array via a for or while loop, or a data file can be read into the array using <fstream> library.

To initialize the array, put the numbers inside a set of curly braces and assign the set to the array.

int arrayOfIntegers[9] = {21, 55, 42, 93, 76, 12, 39, 68};

A for loop can read user input into the array, using i to "step through" the array until it increments to 9, then the reading loop exits. Another loop displays the filled array on the screen after the user enters 9 numbers into the array.

int array[9];
int userinput;

for(int i = 0; i < 9; i++)
{
cout << "Enter an integer: ";
cin >> array[i];
}

for(int i = 0; i < 9; i++)
{
cout << "Numbers in array: " << array[i] << " ";
}

Data can be read from a file containing data (.txt) into an array, but it's a bit more complicated. It still relies on a while loop to handle the copying of the data file's numbers into the array. A constant integer variable, N, holds the size of the array, since it never changes its value and is not supposed to, it can be declared as a constant variable (no operation can edit its value).

fstream is the more generic version of reading in files. A "data stream object" can be defined using fstream, and this object "substitutes" for the actual text file within the program. Any read/write or open/close operations are performed by member functions affecting the data object; so the data file is not actually "inside" the program, but remains separate. 

Instead of specifying the read operation within the file stream, such as ifstream (to read input from a file) and ofstream (to write output to a file), fstream uses a second parameter after the name of the data file string (*.txt), ios:: __. The __ is replaced with the operation that the fstream object needs to perform, namely in for reading input, out for writing output, or app to append data to the end of a data file.

((Strangely, fstream does not seem to work on my linux computer. I've been sticking with ifstream to read in files, but I'm currently baffled as to how fstream, its supposedly simpler cousin, doesn't want to work correctly.))

const int N = 9;
int array[N];
int numbers = 0;

//Object of the input file stream
ifstream data;

//open the data file
data.open("data.txt");
  if(!data)
  {  cout << "Cannot open file." << endl;
  return 0;
  }
  else
  while(numbers < N && data >> array[numbers])
  { numbers++; }

//close the data file
data.close();

Under data.open, an if/else handles the problem of the data file not existing. If the data object is "false" - if .open failed to find the file in the same directory as the program and returned a 1 to the if statement - then the program outputs a message and exits. Otherwise if the file is found, the while loop immediately reads in data from the input stream object data into the array, as long as the incremented variable numbers does not exceed the size of the array, which is 9.

It's a good idea to close the file as soon as the data has been copied to the program's array. This is done with data.close() which closes the connection that data has with the text file.

In general, if for some reason things aren't outputting correctly within a loop, for instance if the array is outputting wrong numbers, try dropping in a cout << of the variable changed immediately before it to check the output of each statement as the loop continues. This has helped me on several programs where a series of couts led to me discover just where the program had an incorrect operation and, in general, helped me to understand how the program's logic flows as it goes through a loop or complicated statement. After any statements are fixed, then comment out the couts and run it again, if the output is correct, then the extra couts used for debugging can be removed.