[Upgrading, Modifying and Unlocking] donhashem.dh:
LESSON 8

Lesson 7 - Structures

Before discussing classes, this lesson will be an introduction to data structures similar to classes. Structures are a way of storing many different variables of different types under the same name. This makes it a more modular program, which is easier to modify because its design makes things more compact. It is also useful for databases.

The format for declaring a structure (in C++, it is different in C) is

Code: [Select]

struct Tag {

Members

};

Where Tag is the name of the entire type of structure. To actually create a single structure the syntax is

Code: [Select]

Tag name_of_single_structure;

To access a variable of the structure it goes

Code: [Select]

name_of_single_structure.name_of_variable;

For example:

Code: [Select]

struct example {

int x;

};

example an_example; //Treating it like a normal variable type

an_example.x = 33; //How to access it's members

Here is an example program:

Code: [Select]

struct database {

int id_number;

int age;

float salary;

};

int main()

{

database employee; //There is now an employee variable that has modifiable

// variables inside it.

employee.age = 22;

employee.id_number = 1;

employee.salary = 12000.21;

}

The struct database declares that database has three variables in it, age, id_number, and salary. You can use database like a variable type like int. You can create an employee with the database type as I did above. Then, to modify it you call everything with the 'employee.' in front of it. You can also return structures from functions by defining their return type as a structure type. For instance:

Code: [Select]

database fn();

I will talk only a little bit about unions as well. Unions are like structures except that all the variables share the same memory. When a union is declared the compiler allocates enough memory for the largest data-type in the union. Its like a giant storage chest where you can store one large item, or a small item, but never the both at the same time.

The '.' operator is used to access different variables inside a union also.

As a final note, if you wish to have a pointer to a structure, to actually access the information stored inside the structure that is pointed to, you use the -> operator in place of the . operator. All points about pointers still apply.

A quick example:

Code: [Select]

#include <iostream>

using namespace std;

struct xampl {

int x;

};

int main()

{

xampl structure;

xampl *ptr;

structure.x = 12;

ptr = &structure; // Yes, you need the & when dealing with structures

// and using pointers to them

cout<< ptr->x; // The -> acts somewhat like the * when used with pointers

// It says, get whatever is at that memory address

// Not "get what that memory address is"

cin.get();

}

LESSON 8

Lesson 8 - Arrays

Arrays are useful critters because they can be used in many ways. For example, a tic-tac-toe board can be held in an array. Arrays are essentially a way to store many values under the same name. You can make an array out of any data-type including structures and classes.

Think about arrays like this:

Code: [Select]

[][][][][][]

Each of the bracket pairs is a slot(element) in the array, and you can put information into each one of them. It is almost like having a group of variables side by side. Lets look at the syntax for declaring an array.

Code: [Select]

int examplearray[100]; // This declares an array

This would make an integer array with 100 slots, or places to store values(also called elements). To access a specific part element of the array, you merely put the array name and, in brackets, an index number. This corresponds to a specific element of the array. The one trick is that the first index number, and thus the first element, is zero, and the last is the number of elements minus one. 0-99 in a 100 element array, for example.

What can you do with this simple knowledge? Lets say you want to store a string, because C++ has no built-in datatype for strings, you can make an array of characters.

For example:

Code: [Select]

char astring[100];

will allow you to declare a char array of 100 elements, or slots. Then you can receive input into it it from the user, and if the user types in a long string, it will go in the array. The neat thing is that it is very easy to work with strings in this way, and there is even a header file called cstring. There is another lesson on the uses of strings, so its not necessary to discuss here.

The most useful aspect of arrays is multidimensional arrays. How I think about multi-dimensional arrays:

Code: [Select]

[][][][][]

[][][][][]

[][][][][]

[][][][][]

[][][][][]

This is a graphic of what a two-dimensional array looks like when I visualize it.

For example:

Code: [Select]

int twodimensionalarray[8][8];

declares an array that has two dimensions. Think of it as a chessboard. You can easily use this to store information about some kind of game or to write something like tic-tac-toe. To access it, all you need are two variables, one that goes in the first slot and one that goes in the second slot. You can even make a three dimensional array, though you probably won't need to. In fact, you could make a four-hundred dimensional array. It would be confusing to visualize, however. Arrays are treated like any other variable in most ways. You can modify one value in it by putting:

Code: [Select]

arrayname[arrayindexnumber] = whatever;

or, for two dimensional arrays

Code: [Select]

arrayname[arrayindexnumber1][arrayindexnumber2] = whatever;

However, you should never attempt to write data past the last element of the array, such as when you have a 10 element array, and you try to write to the [10] element. The memory for the array that was allocated for it will only be ten locations in memory, but the next location could be anything, which could crash your computer.

You will find lots of useful things to do with arrays, from storing information about certain things under one name, to making games like tic-tac-toe. One suggestion I have is to use for loops when access arrays.

Code: [Select]

#include <iostream>

using namespace std;

int main()

{

int x;

int y;

int array[8][8]; // Declares an array like a chessboard

for ( x = 0; x < 8; x++ ) {

for ( y = 0; y < 8; y++ )

array[x][y] = x * y; // Set each element to a value

}

cout<<"Array Indices:\n";

for ( x = 0; x < 8;x++ ) {

for ( y = 0; y < 8; y++ )

cout<<"["<<x<<"]["<<y<<"]="<< array[x][y] <<" ";

cout<<"\n";

}

cin.get();

}

Here you see that the loops work well because they increment the variable for you, and you only need to increment by one. Its the easiest loop to read, and you access the entire array.

One thing that arrays don't require that other variables do, is a reference operator when you want to have a pointer to the string. For example:

Code: [Select]

char *ptr;

char str[40];

ptr = str; // Gives the memory address without a reference operator(&)

As opposed to

Code: [Select]

int *ptr;

int num;

ptr = &num; // Requires & to give the memory address to the ptr

The reason for this is that when an array name is used as an expression, it refers to a pointer to the first element, not the entire array. This rule causes a great deal of confusion.

LESSON 8

Lesson 9 - Strings

In C++ there are two types of strings, C-style strings, and C++-style strings. This lesson will discuss C-style strings. C-style strings are really arrays, but there are some different functions that are used for strings, like adding to strings, finding the length of strings, and also of checking to see if strings match. The definition of a string would be anything that contains more than one character strung together. For example, "This" is a string. However, single characters will not be strings, though they can be used as strings.

Strings are arrays of chars. String literals are words surrounded by double quotation marks.

Code: [Select]

"This is a static string"

To declare a string of 49 letters, you would want to say:

Code: [Select]

char string[50];

This would declare a string with a length of 50 characters. Do not forget that arrays begin at zero, not 1 for the index number. In addition, a string ends with a null character, literally a '\0' character. However, just remember that there will be an extra character on the end on a string. It is like a period at the end of a sentence, it is not counted as a letter, but it still takes up a space. Technically, in a fifty char array you could only hold 49 letters and one null character at the end to terminate the string.

TAKE NOTE: char *arry; Can also be used as a string. If you have read the tutorial on pointers, you can do something such as:

Code: [Select]

arry = new char[256];

which allows you to access arry just as if it were an array. Keep in mind that to use delete you must put [] between delete and arry to tell it to free all 256 bytes of memory allocated.

For example:

Code: [Select]

delete [] arry.

Strings are useful for holding all types of long input. If you want the user to input his or her name, you must use a string. Using cin>> to input a string works, but it will terminate the string after it reads the first space. The best way to handle this situation is to use the function cin.getline. Technically cin is a class (a beast similar to a structure), and you are calling one of its member functions. The most important thing is to understand how to use the function however.

The prototype for that function is:

Code: [Select]

istream& getline(char *buffer, int length, char terminal_char);

The char *buffer is a pointer to the first element of the character array, so that it can actually be used to access the array. The int length is simply how long the string to be input can be at its maximum (how big the array is). The char terminal_char means that the string will terminate if the user inputs whatever that character is. Keep in mind that it will discard whatever the terminal character is.

It is possible to make a function call of cin.getline(arry, 50); without the terminal character. Note that '\n' is the way of actually telling the compiler you mean a new line, i.e. someone hitting the enter key.

For a example:

Code: [Select]

#include <iostream>

using namespace std;

int main()

{

char string[256]; // A nice long string

cout<<"Please enter a long string: ";

cin.getline ( string, 256, '\n' ); // Input goes into string

cout<<"Your long string was: "<< string <<endl;

cin.get();

}

Remember that you are actually passing the address of the array when you pass string because arrays do not require an address operator (&) to be used to pass their address. Other than that, you could make '\n' any character you want (make sure to enclose it with single quotes to inform the compiler of its character status) to have the getline terminate on that character.

cstring is a header file that contains many functions for manipulating strings. One of these is the string comparison function.

Code: [Select]

int strcmp ( const char *s1, const char *s2 );

strcmp will accept two strings. It will return an integer. This integer will either be:

Code: [Select]

Negative if s1 is less than s2.

Zero if s1 and s2 are equal.

Positive if s1 is greater than s2.

Strcmp is case sensitive. Strcmp also passes the address of the character array to the function to allow it to be accessed.

Code: [Select]

char *strcat ( char *dest, const char *src );

strcat is short for string concatenate, which means to add to the end, or append. It adds the second string to the first string. It returns a pointer to the concatenated string. Beware this function, it assumes that dest is large enough to hold the entire contents of src as well as its own contents.

Code: [Select]

char *strcpy ( char *dest, const char *src );

strcpy is short for string copy, which means it copies the entire contents of src into dest. The contents of dest after strcpy will be exactly the same as src such that strcmp ( dest, src ) will return 0.

Code: [Select]

size_t strlen ( const char *s );

strlen will return the length of a string, minus the termating character ('\0'). The size_t is nothing to worry about. Just treat it as an integer that cannot be negative, which it is.

Here is a small program using many of the previously described functions:

Code: [Select]

#include <iostream> //For cout

#include <cstring> //For the string functions

using namespace std;

int main()

{

char name[50];

char lastname[50];

char fullname[100]; // Big enough to hold both name and lastname

cout<<"Please enter your name: ";

cin.getline ( name, 50 );

if ( strcmp ( name, "Julienne" ) == 0 ) // Equal strings

cout<<"That's my name too.\n";

else // Not equal

cout<<"That's not my name.\n";

// Find the length of your name

cout<<"Your name is "<< strlen ( name ) <<" letters long\n";

cout<<"Enter your last name: ";

cin.getline ( lastname, 50 );

fullname[0] = '\0'; // strcat searches for '\0' to cat after

strcat ( fullname, name ); // Copy name into full name

strcat ( fullname, " " ); // We want to separate the names by a space

strcat ( fullname, lastname ); // Copy lastname onto the end of fullname

cout<<"Your full name is "<< fullname <<"\n";

cin.get();

}

LESSON 10

Lesson 10 - File I-O

This is a slightly more advanced topic than what I have covered so far, but I think that it is useful. File I/O is reading from and writing to files. This lesson will only cover text files, that is, files that are composed only of ASCII text.

C++ has two basic classes to handle files, ifstream and ofstream. To use them, include the header file fstream. Ifstream handles file input (reading from files), and ofstream handles file output (writing to files). The way to declare an instance of the ifstream or ofstream class is:

Code: [Select]

ifstream a_file;

or

Code: [Select]

ifstream a_file ( "filename" );

The constructor for both classes will actually open the file if you pass the name as an argument. As well, both classes have an open command (a_file.open()) and a close command (a_file.close()). You aren't required to use the close command as it will automatically be called when the program terminates, but if you need to close the file long before the program ends, it is useful.

The beauty of the C++ method of handling files rests in the simplicity of the actual functions used in basic input and output operations. Because C++ supports overloading operators, it is possible to use << and >> in front of the instance of the class as if it were cout or cin. In fact, file streams can be used exactly the same as cout and cin after they are opened.

For example:

Code: [Select]

#include <fstream>

#include <iostream>

using namespace std;

int main()

{

char str[10];

//Creates an instance of ofstream, and opens example.txt

ofstream a_file ( "example.txt" );

// Outputs to example.txt through a_file

a_file<<"This text will now be inside of example.txt";

// Close the file stream explicitly

a_file.close();

//Opens for reading the file

ifstream b_file ( "example.txt" );

//Reads one string from the file

b_file>> str;

//Should output 'this'

cout<< str <<"\n";

// b_file is closed implicitly here

}

The default mode for opening a file with ofstream's constructor is to create it if it does not exist, or delete everything in it if something does exist in it. If necessary, you can give a second argument that specifies how the file should be handled. They are listed below:

Code: [Select]

ios::app -- Append to the file

ios::ate -- Set the current position to the end

ios::trunc -- Delete everything in the file

For example:

Code: [Select]

ofstream a_file ( "test.txt", ios::app );

This will open the file without destroying the current contents and allow you to append new data. When opening files, be very careful not to use them if the file could not be opened. This can be tested for very easily:

Code: [Select]

ifstream a_file ( "example.txt" );

if ( !a_file.is_open() ) {

// The file could not be opened

}

else {

// Safely use the file stream

}