Tuesday, October 24, 2006

File Streams and Text Files

Files are simply a long stream of binary bits of data. The use of files depends on what the file is made up of; more or less, each file is written with a sort of pattern to make it possible to read it again and write it again.

The most common form of file is the "Text" file. The text file is basically filled with binary values from the ASCII character set (see previous graphic for more details on that). The pattern for the average text file is that for one, it will not hold any data other than the first 127 bites of the ASCII table (yes, there are exceptions, but this is the "basic" text file), there will be "End of Line" markers that will tell programs when to stick in a carriage return, and then there might be an end of file marker.

In a moment of non sequiter theatre, lets point out that the "End of Line" marker is different based upon the operating system involved. In Windows, the end of line is marked with a "Carrage Return" plus a "Line Feed" character, where as many unix systems only use "Carriage Return." Knowing what your text file is made up of is important before you commit to one method or another.

The methods of reading these files are so common and so often used, that just about every compiler has ways to read them. "Getline()" method will read from the first of the file, to the end of line marker, and return what it finds. "Writeline()" will write out a text line and include the end of line marker automatically. "eof()" will test if the text file is at the end of the file.

If you would consider a text file like a paragraph made up of rows and columns. Each row and column has a letter that fits inside that paragraph. Consider this picture:

[{tab}][I][{space}][a][m][{space}][a][{carriage return}][{line feed}]
[s][i][m][p][l][e][{space}][t][e][x][t][{carriage return}][{line feed}]
[f][i][l][e][{end of file}]

As you read from the text file, a cursor is advancing through each column and row as you pull data out. Once it reaches the end, no more data can be pulled.

Wednesday, October 18, 2006

Arrays Again


Memory on computers are a structured, ordered system. A spreadsheet is a wonderful way to represent it; if you look at the diagram, you see two aspects. One is the Address of the memory and the other is the contents of the memory. In general the memory is a certain uniform size: 8 bites. Things like characters can fit in a single address. Others, like Long Integers, have to fit in two memory addresses.

Arrays and pointers are addresses that contain addresses to other areas. This allows you to write programs dynamically instead of having to have set memory sets.

One array living at 0x0002 can possibly point to an array over in 0x0016 (this is a simplified view; its more complicated than that, but dont worry about it). The array starts at 0x0016 and keeps going until 0x0022.

Monday, October 09, 2006

File Streams Again



I would like to throw out some extra information about files. The above diagrams are two bits of important information. One is the general accepted heiarchy for the file streams. The second is one of the ASCII character sets. Knowing these numbers are important for dealing with files.

Consider the following file as an input example:

1,"Indionapolis, IN",$22.33,A1C
2,"Phoenix, AZ",$12.53,A3C
3,"Los Angeles, CA",$26.03,A5C
4,"Huston, TX",$2.83,A3C
5,"Fargo, MN",$42.33,A1C

Try out the following source code; this is the start of an idea to read in such a file. What are the limitations? What are the strengths? How can this work better?



Created with colorer-take5 library. Type 'cpp'

#include <iostream.h>
#include <fstream.h>

int main( )
{
char filename[255];
char tmpStr[300];
char qr;
int tmpint=0;
int x;

cout << "\n\n\nCSV FILE TESTER\n\n\n";
cout << "Enter the name for the CSV File: ";
cin >> filename;

if ( strlen( filename ) == 0 ) {
cerr << "Blank filename" << endl;
exit( 1 );
}

ifstream inFile( filename, ios::in );

qr = ' ';
while ( !inFile.eof() )
{
inFile.getline(tmpStr, 299);

x = 0;
while ( x < strlen(tmpStr) ){
qr = tmpStr[x];
if (qr == ',')
cout << " \n";
else if (qr == '"')
{
cout << '"';
x++;
qr = tmpStr[x];
while ( ( !inFile.eof() ) && ( qr != '"' ) )
{
qr = tmpStr[x];
cout << qr;
x++;
}
cout << '"' << endl;
}
else
cout << qr;
x++;
}
cout << endl;
}
cin.ignore();
return 0;
}

Friday, October 06, 2006

COMMENTARY

I know this board is rather slapshod right now; I literally threw it together out of a document I wrote for one person. But I grew to love that document so much that I decided to create this blog and eventually add to it.

This blog may never take off, or it may become popular. Who knows. But in the mean time, it'll be my sounding board to share things.

In the mean time, I have collected some more sample code for use with the material up until now.
The can be found on my other sight.

Also; I have many suggestions as to what compiler to use in order to try and test everything. My personal favorites are all of the borland products. Borland Delphi, C++ Builder, C# Builder. But if you want free, there is the
Delorie GCC project, The Zipslack / Monkey Linux Project, the Bloodshed C++/Pascal Project, and Borland's "Classic" versions of old Turbo Pascal/C++ compilers. Additionally, some very good commercial compilers have gone open source, like the Watcom compiler.

I will also be putting up possilbe practice projects for those who are interested.

Wednesday, October 04, 2006

Reusing Code

8.0 Reusing Code

The concept of reusing code seems a bit obvious, but it’s the most often ignored concept. If you ever do something right, its best to set it up to be easily used over and over again. Lets say you want to write a line of dashes across the screen whenever you want. You could just write out something like this:

for (x=0;x<80;x++)
cout << ‘-‘;

but this is a bit redundant if you have to do this over and over again. What if you could just call a library or something to do the same thing? Well..you can make one up yourself. Consider the following program:

#include <iostream.h>

void printdash()
{
for( int x=0; x<80; x++ )
cout << ‘-‘;
cout << “\n”;
}

int main()
{
printdash();
cout << “menu option 1)\n”;
cout << “menu otpion 2)\n”;
cout << “menu option 3)\n”;
printdash();

return 0;
}

Whenever you needed to print out the line, you just called the function called “printdash” and it worked. Now all functions require a return value, and in this case the return value is “void” or basically nothing. It could be used to return an integer, a float or whatever. Consider the function to square the value of a number:

double sqare( double value )
{
return a*a;
}

the key word “return” is used to send the value back as a number, and can be even used as a number value.

Q = Q * square(24);

(In fact...if you’ve noticed...most “main()” functions also return a number. This is a hold over to the original use of C, namly UNIX made by Bell Labs. This is to tell the operating system one thing or another about how the program did. In most cases, returning zero works just fine).

8.1 Reusing Arrays in Functions

Now what if you need to pass an array? Remember the whole point of arrays is that the variable itself is a pointer to the first element of the array. So if you wanted to pass an array of characters, when it gets to the function, the array becomes a pointer of characters.

int printValue( char* value )
{
cout << value;
return 1;
}

int main()
{
char name[200];
strcpy( name, “Philip Milkenstien Wiskerstern” );
printValue( name );

return 0;
}

8.2 Reusing Code with Changing Variables

Now what if you wanted to use a function to change values in the functions. Remember the whole idea that variables are pointers to addresses that contain the actual values. This works the same way with functions; you can pass variables “by value” or “by address.” When you pass information “by value” then only the information gets passed in. No matter what happens inside the function, nothing in the variable will be changed. However, when you pass by address, then the actual address of the variable gets passed in, and everything you do to the variable will change its contents. This is often referred to as “side effects,” mainly because it is considered bad practice to rely upon side effects to change the value of a variable. However, there are always situations where this is a good idea. In most cases, relying upon the returned value is more appropreate.

The following is an example of something called a “bubble sort”, the most basic and common way to sort values.

#include <iostream.h>

void swapit( int& a, int& b )
{
int temp=a;
a = b;
b = temp;
}

main()
{
int array[10] = { 1, 35, 53, 22, 55, 66, 4, 42, 44, 65 };
int n=10;
int x,y;

for (x=0; x<n; x++)
cout << " Index #" << x << ") " << array[x] << "\n";

for(x=0; x<n; x++)
{
for(y=0; y<n-1; y++)
{
if(array[y]>array[y+1])
{
swapit( array[y], array[y+1] );

}
}
}
cout << "\n\n";
for (x=0; x<n; x++)
cout << " Index #" << x << ") " << array[x] << "\n";
}

The passed in function holds the address, and allows the values to be changed and used in the function.

File Streams

7.0 File Streams

Getting information from different places is important. Until now, we’ve only gotten info from the iostream using cin and cout. Now, we’ll get info from text files using the file stream, using the fstream.h header. This works the same way as when we did the others, but instead of sending text and information to the screen, when you create a variable using the fstream, you send information to a file. Here’s an example of opening a file to read:

ifstream inData( “datafile.txt”, ios::in );
char tmpStr[40];

if ( !inData ){
cout << “whopse...couldn’t open \”datafile.txt\” for input.\n”;
exit( 1 );
}

while( inData > > tmpStr )
cout << tmpStr << “\n”;

File streams are created by the same method as any other variable, with “ifstream” as the variable type, and your name for the variable next (in our case, “inData”). The only difference is that ifstream’s are what is called an “object”; objects are declaired different than any other variable. (We’re not gonna go into objects just yet...just realize that you must declair filestreams a little different than any other variables).

The main thing about creating a file stream is that you are actually opening the file itself for editing, reading, appending, etc. You supply the name of the file you want to open or create, and then how you want to use the file. In the above case, we’re using the “in” mode, or “read only” mode. (If you’re curious, “ios” is apart of the iostream library. Its kinda complex, but basically, you’re telling the compiler, “go find ‘ios’ and give me the ‘in’ part). Technically, because “ifstream” is naturally a “in” object, you can leave out the “ios::in” part, and it will assume the rest, however, its always best to include that part, just to make sure. (ofstream’s are for outputting files).

Information is grabbed out of files the same way as standard cin and cout, by using the double arrows <<> > . The end of file is reached when no more data can be extracted; basically when it returns Zero. Since its returning zero or a huge number, you can test for it with a boolean operation, like “while( inData > > tmpStr )” and so forth.

7.1 The File Gotchyas

There are a few things to remember about filenames. Filenames are based upon the Operating System, and not the compiler. Window 3.1 will behave differently than WindowXP; and will behave differently than Linux. Know you’re filenames, play with spaces, paths and so forth.

7.2 Modes of Files

Here’s a list of ways to open up files:

ios::app Write all output to the end of the file.
ios::ate Open a file for output and move to the end of the file (normally used to append data to a file). Data can be written anywhere in the file
ios::in Open a file for input
ios::out Open a file for output
ios::trunc Discard the file’s contents if it exists (this is the default action for ios::out options)
ios::binary Open a file for non-text input or output.

Those Evil Pointers

6.0 Those Evil Pointers

The most powerful tool for any programmer is also the most feared…but it doesn’t havta be. Pointers are something you’ve been using ever since you started making variables in one way or another. Its just a way to make variables work exactly the way you need to make them work, and make them work as fast as possible.

What are pointers? Well, think back to the maps we drew about the arrays. Remember how each array had an “origin” that pointed to another location in memory that started the array of memory? Pointers work the same way, except that they don’t get assigned memory spaces, UNTIL the program is ACTUALLY RUN. Think about it..how often do you know exactly how many you will need at any one time. If you setup a program to load 20 budget items, how much memory do you waste only doing 8? What happens if you suddenly need 25 items? Pointers allow you to declair how much you need at the time you actually run it.

So why do people get so scared of pointers? Pointers can make your programs work fast, efficient and all that catnip & fuzzy mice stuff…IF they are done right. If they are done wrong…well…bad things happen…catnip gives you bad trip….fuzzy mice bite back…etc. So…the answer is: Do Pointers Right. > ^.^< m

6.1 Pointer Basics

The basic start for creating a pointer is to use the standard pointer reference. In C/C++, it’s the “*” astarisk next to the declairation.

char* names;
int* values;

In Pascal, the pointer is done with the “^” caret after the variable.

Names: ^String;
Values: ^Integer;

6.2 WC for Computers

Now once you’ve declaired a variable of this type, you have an empty address…remember…all pointers do is store addresses, so you can’t try to use them until you put an address in them. This works by telling the computer to take a small section of memory of the size you want, and reserve it for the use of your program. This allocation of memory is the source of most bugs in many programs, mainly because of something called a “Memory Leak”--basically, when programs tells the operating system to reserve bits of memory, but never releases that memory, then all of a sudden your computer has a bunch of memory that can’t be used by anything until it is fixed. Some programming languages like Java and Smalltalk use something called “Garbage Collection” where the actual cleanup of unused memory is taken care of by other systems. This is very debatable which way is better because nobody can agree on the “best” way to do garbage collection and the whole garbage collection system ALWAYS makes things much slower and visiable to the user. Essentially, every programmer must know both ways in order to be able to get the most outta their programs.

6.3 Memory Dynamics

To give your pointer variables substance, you have to tell the computer what you want to create, and how many. A single integer for instance would look something like this (in C++):

Int* x;
x = new int;
….. do something…..
delete x;

The keyword “new” creates the new memory space based upon the size of the variable. After you use the variable, the keyword “delete” cleans up the memory. To create an array of items, simply add a demention parameter just like you would in array.

char* names;
names = new char[200];
…. Do something ….
delete [] names;

the extra “[]” tells the compiler to remove the array.

6.4 Alternate Addressing

One odd thing about pointers is that you generally have to use them differently than other types of variables. Normal variables are setup to give you direct access to the contents; there’s no need to do anything special to get to the contents of the memory. However, Pointers are automatically addresses that will not even have memory spaces until you setup some memory AND assign it for it to use. Therefore, pointers must be used in a different way.

Consider:

int* x;
x = new int;

we’ve got an integer pointer, and it has memory. If you did a simple “cout”

cout < < x;

you would get a hexadecimal number that is the actual address of the variable. But if you want to do something with it, you have “dereference” the variable. There are bunches of different ways to do this. For our integer (and most single variables) in C++ it looks like this:

*x=100;
cout < < *x;

And…you’ll get what you’re after. For structures, you need to access each member with an arrow (-> ) instead of a dot. SO, if you consider this:

struct data{
int a;
int b;
}
data one;
data *two;

one.a = 20;
one.b = 30;

two = new data;
two-> a = 20;
two-> b = 30;
delete two;

Each language is different; so double-check each kind in your quick reference manual.

6.5 Secret Pointer Plots

You can do many different wonderful things with pointers. There are millions of mathmatitians and computer scientists thinking up new algorithms (here’s the offical definition: Algorithm n : a precise rule (or set of rules) specifying how to solve some problem [syn: algorithmic rule, algorithmic program]. Basically, an “algorithm” is the way you describe how to do something but using a few details as possible. Kinda like describing how to make a tuna fish sandwitch without using the words “tuna”, “bread” or “GIMMIE MY TUNA FISH BACK”). These algorithms make things work out a lot easier and faster, and there are lots available. But the most common ones are great to learn and very useful.

“Linked Lists” are a combination of structures and pointers to give you a complex list of data in memory that you can grow and shrink without any problems. There are sooo many versions and applications of this idea that it’s very important to try to understand the basic idea. The idea is that you create a structure with all of your information, then you add in a pointer to another instance of the same structure. Then, you create a bunch of these, with each structure pointing to the next copy of the structure until you have all the information you need.

[Info ]
[Pointer]---------> [Info ]
[Pointer]---------> [Info ]
[Pointer]---------> NULL

and so on. By using a pointer inside the structure, there is no reason or need to declair a bunch of variables. You declair one copy in your program, but you then can use the “new” command (or whatever command is right for your language) and reuse the pointer inside the structure itself.

6.5.1 OOO…look what I found

Source: The Free On-line Dictionary of Computing (2003-OCT-10)

algorithm

<> A detailed sequence of actions to perform to accomplish some task. Named after an Iranian mathematician, Al-Khawarizmi. Technically, an algorithm must reach a result after a finite number of steps, thus ruling out brute force search methods for certain problems, though some might claim that brute force search was also a valid (generic) algorithm. The term is also used loosely for any sequence of actions (which may or may not terminate).

Paul E. Black's Dictionary of Algorithms, Data Structures, and Problems. (2002-02-05)

6.6 Link List Example

#include <>

struct node{
int data;
node* ptr;
};

main()
{
// a "Cursor" is a pointer to some point in the list,
// so you dont get lost. Temporary variables like
// this are often used.
node* myinfo;
node* cursor;
int x;

myinfo = new node;
cursor = myinfo;

for( x=100; x< 200; x++ )
{

// normally, link lists will end with a "NULL" to tell the ending;
// we're just using a counter, so we know how many.
myinfo-> data = x;
myinfo-> ptr = new node;
myinfo = myinfo-> ptr;
myinfo = NULL;

}
myinfo = cursor;
for ( x=100; x< 200; x++ )
{
cout < <> data < < "\n";
myinfo = myinfo-> ptr;
// clean up as we walk through
delete cursor;
cursor = myinfo;
}
}

Memory Marching Madly

5.0 Memory Marching Madly

We know now that when you declair a variable, you are reserving memory to use. This memory is statically set in a section of memory, but in a random available section somewhere out there in the computer’s memory. You could declair two variables one right after each other and they can have dramatically different addresses. The variable itself stores the address to where the data is stored; you could even refence that variable so you can read the hexadecimal location of where it is located for study.

But what about cases when you want to have a bunch of information collected together in a row. You could declair 52 varibables to store the amount of money you spent in a particular week of the year. And if you wanted to collect a bunch of characters together to spell out actual words. This is what is call as an “Array.”

5.1 Arrays

Arrays variables work in a similar way to normal variables in that they reserve space. However, they are specially designed to server a group of continuous spaces of memory. The variable itself actually just points to the first “space” in that array. One feature of an array is that they must “homogenius” data types…that just means they all have to be the same type. No mixing allowed.

5.2 Getting the words out

One special type of array is an array of characters, also called “Strings.” While…my first impulse is to chase strings, these are just strings of characters. The main idea is that the most common thing any computer will ever do is to put words together to display information. Most compilers have whole librarys dedicated to just dealing with “strings” (C/C++ has ). Some common string functions are: “Trim” to clean out any control characters, like tab or spaces, “Substring” will tell you were inside a big string is an instance of a smaller string, so you can find patterns or locations.

5.3 “Hello Array!” Addressing of Arrays and Address Jumping

Variables that are arrays must be addressed differently than your avarage non-array variable. Lets say your array is named “strName,” if you just used the word “strName” in your program, you are just dealing with the ADDRESS of the FIRST space in the row of variables you declaired. Look at it this way:

Actual Container of Info strName
___ ___
_a_ << = = = = = = = = = = =___
_b_
_c_
_d_
_e_
_f_
_g_

The variable strName just contains the address of where the actual content of the array is stored in memory, with the letters “abcdefg.” So if you want to deal with the content, you have to address the array variables differently. You must provide an “index” to the array, based upon the position in the array from the first. So “a” is located in the “zero” index, because its in the first box, right where the address is pointing to. But the letter “c” is 2 from the first, and therefore is in the 2nd index. So to access the “a” in the variable “strName” you would use the addressing of “strName[0]” and to access the “c” you would use the addressing of “strName[2].” (NOTE: most string handling functions do most of this indexing already, so you will only need to pass in the “strName” to get anything done; however if you need to address individual parts, then you need to figure out the indexing yourself.)

One thing to remember is that since strName has the address, and the compiler knows how big the size of each variable is, then what would happen if you increment that variable? This nifty trick is: it points to the next spot on the list! So in the above picture, if you did “strName++” the new picture would look like this:

Actual Container of Info strName
___
_a_ ___
_b_ << = = = = = = = = = = =___
_c_
_d_
_e_
_f_
_g_

The address has changed, and you now have a new set of indexes. This is a common short cut for faster access to memeory; however, it only works in some compilers. But the principle is important to know: Addresses can be added and subtracted. This is called “pointer arithmatic” but its not important for now.

5.4 How do you know you are done?

One important idea to go over again is the fact that even though you declaired a variable, even arrays, it doesn’t mean the memory is empty. It most likely will contain junk values left over from another program. So..if you have an array, how do you know you are done? There are 2 schools of thought to solve this. The first idea is back to our sentinel value. A character that couldn’t possibly be used, and what they have chosen is the “NULL” character. The null value is universally a unusuable character, which is essentially Zero. So, what this means is that if you always have to add one to every calculation (although most string-handling functions will do this for you) to account for the null character at the end. IF you want to fit the alphebet in an array, you will need space for 27 characters, instead of just 26. The second school of thought is called a “Pascal” string (named after a mathmetician “Blaise Pascal”) that uses the first character in the string to tell the length of the string. Therefore, the first index will always be a number, but the others will be the actual characters. The draw back is that for normal characters, no string can be longer than 255 in length. (Except for “wide” characters that are much bigger).

5.5 Memory of Memory of Memory

So what about going multi-dementional? Lets just say you have a spreadsheet that shows how much you spent on stuff over the month of November? For one, we want an array of names telling what we spent money on. For another, we want what we spent money on, and the days we are talking about.

Lets say the list of things we spend on in our budget. Lets assume no more than 20 items, of no more than 100 characters long. So, in C++, it would look like this:

char budget[20][100];

If we would scketch this out, it would look something like this:

[ ] ----> [ ] ------> [R][e][n][t][NULL][ ][ ][ ][ ]
[ ] ------> [F][o][o][d][NULL][ ][ ][ ][ ]
[ ] ------> [G][a][s][NULL][ ][ ][ ][ ][ ]
[ ] ------> [ ][ ][ ][ ][ ][ ][ ][ ][ ]
[ ] ------> [ ][ ][ ][ ][ ][ ][ ][ ][ ]
[ ] ------> [ ][ ][ ][ ][ ][ ][ ][ ][ ]

The idea is that the first cell points to the first cell of the first array of 20 characters, so basically it’s “root” or “origin” of the variable. The first array of 20 characters isn’t really a character, but are again pointing to the NEXT set of arrays, each being 100 characters wide. These are the spots in memory that actually have the information. So, if you wanted to find the word “Gas,” you would start at the origin, move to the 3rd index (which is #2) and you find the word “Gas.” In C++, it would look like this:

cout << budget[2];

Now lets think about the actual money. Budgeting November would include a total of 30 days and 20 different items (referring back to our budget names). Lets make it 31 days, just so we can use the same source code for other months. But what kind of variable should we use to represent money? You might think float, because…there’s fractions in dem dar dollars. But really, what happens when you suddenly have 0.125 dollars? You can’t…most people just round out fractions with money…except for banks & governments…so a better idea is to use int to count pennies, and when we want to print things out, we just divide by 100 to get the right decimal. So we might see it like this:

int intSpentItems[20][31];

this might look like this:

[ ] ----> [ ] ------> [100][123][233][4000][NULL][ ][ ][ ][ ]
[ ] ------> [123][334][4999][5999][NULL][ ][ ][ ][ ]
[ ] ------> [ ][ ][ ][ ][ ][ ][ ][ ][ ]
[ ] ------> [ ][ ][ ][ ][ ][ ][ ][ ][ ]
[ ] ------> [ ][ ][ ][ ][ ][ ][ ][ ][ ]

Very similar to our budget, and we’d access it in a similar way:

cout << “budget item \”” << budget[2] << “\” had “ << intSpentItems[2][x] << “ on the “ << x << “ of November.\n”;

But what if we wanted to record not only how much spent, but also how much we planned on spending. Do we need another array? We could, but how about adding another demention to that array to make things easier.

int intSpentItems[20][2][31];

Now we have a 3 dementional array. Lets try to draw how this will work:


[ ] ---->[ ]------>[]--->[104][150][200][4000][NULL][ ][ ][ ][ ]
[]--->[100][123][233][4000][NULL][ ][ ][ ][ ]
[ ]------>[]--->[123][334][4999][5999][NULL][ ][ ][ ][ ]
[]--->[100][123][233][4000][NULL][ ][ ][ ][ ]
[ ]------>[]---> [ ][ ][ ][ ][ ][ ][ ][ ][ ]
[]---> [ ][ ][ ][ ][ ][ ][ ][ ][ ]
[ ]------>[]---> [ ][ ][ ][ ][ ][ ][ ][ ][ ]
[]---> [ ][ ][ ][ ][ ][ ][ ][ ][ ]

Again, we have the same origin point, pointing to the start of an array of more origins, pointing to another array of origins pointing to an array of integers. Now we have a useful, multimentional array full of possibilities.

5.6 Memory Clubbing

There often times when you have many different variables that are directly related to each other, even if they aren’t the same kind. The example of the list of expendatures and list of labels is a perfect example. One was integer and the other was strings of words. Now you can just take those variables and declair them seperatly and everything will work just fine. But if you wanted to be very clear about what you were doing, especially if you wanted to reuse your source code over and over again, you might consider something called a “memory structure.”

A Memory Structure is a group of variables stuck together, much like arrays are--one right next to the other--but they can be of different types of data. The structure becomes one variable made up of different members of its own little party. (This is often refered as a single “object” but its no EXACTLY what you would consider an object, but remember that name for later.) That way, you can declair a single variable to contain a whole bunch of information to use all over the place.

5.7 Structured Examples

Lets redo our budget as a structure, using C++ wordings:

struct MyBudget {
char budget[20][100];
int intSpentItems[20][31];
}

That simple. And it looks just like we did before…just within the “struct” command. When you use it, you just declair a variable the same way you would any other variable, but of type “MyBudget.”

MyBudget data;

To get to the different parts or memebers of that structure, you use a “dot” notation (fancy way of saying “put a period”).

strcpy( data.budget[0], “Food” );

Neato speado, eh? SO…how would this map out? VEERY similar to the array! The info gets all jumbled together so you can grab at it the same way. In fact, since we’ve got 20 items grouped together this way, we can get even fancier and clearer for our programming. Why have multi-dementional array when want to be VERY clear that each label gets tagged along with whats getting spent on it. How does this look?

struct MyBudget {
char label[100];
int intActualSpent[31];
int intPlannedSpent[31];
}

MyBudget data[20];

It works the same way, but now each label has both the actual spent and the planned spent spelled out in the array, so there’s no confusion as what each part is gonna be used for. This is a very common way programmers use to make things clearer and more efficient, even though both ways still work.

Blah! TWO! TWO MATHMATICAL OPERATORS!! MUHAHAHAHAH!!

4.0 Blah! TWO! TWO MATHMATICAL OPERATORS!! MUHAHAHAHAH!!

Doing math is often used as a logical test as much as … doing any math. You can do just so many useful things with simple mathmatical formulae. Some are obvious, some a little strange. Its just a question of getting used to the tools you are using.

4.1 The Basics

Addition, subtraction, division and multiplication are general deal with the obvious symbols; “+”, “-“, “/” and “*” respectivly. In some languages, such as pascal, if you want to only do INTERGER division, you have to use the word “DIV” instead. In other languages, such as C/C++, it is controled by what memeory variables you are using.

4.2 Conquering the Divisions

Division is important concept in many cases, because of the potential problems involved. When you divide floating-point numbers, you will introduce a rounding error in the result depending on how big the number you are using (look up at memory variable sections again). Another part is that computers get really upset when you try to divide by zero. Hardware and software are a lot better now to catch this thing, but you should always check to make sure if your divisor is zero if there is the remote posibilty of it being zero.

4.3 Other functions

Modulus is the operation that tells you the remainder of dividing two numbers. So 10 modulus 5 would be zero, but 12 modulus 5 would be 2. In C/C++ and Java this is done buy the percent symbol “%” but in languages like pascal and basic, the word “MOD” is used.

Raising a number to a power or taking the square root of any number is general done with functions. Most languages will have an available math library to supply this functionality.

Equality and Assignment are often confused. For C/C++ and Java, the symbol to test if two values are equal is always two equal signs “==” and to assign one value to another value is only one equal sign “=”. This is often a source of confusion. Languages like Pascal use a sepcial “:=” symbol to show assignment and a single “=” to show equality. Languages like basic use “=” for both equality and assignment.

In some very rare cases you will need to shift the bits in a variable. If you look back to the “encoding” section, you can see that everything is stored in bit form, usually in groups of eight bits. But if you look at the four bit list up there….say the number 4, is 0100. Lets say you move all the bits over left by just one, you’d get 1000, or 8. What did that just do? Yep, multplied the number by 2. What if you moved the bits over right by one, you’d get 0010 or 2. What did that do? Divided the number by 2. So what “Shift Bits Left” and “Shift Bits Right” does is to either multply or divide the bits by 2. This has the unique benefit of being very VERY fast. In most languages the command is shl for left and shr for right.

4.4 Enough rope to…play jumprope

One of the quirks to many languages, like C/C++, is the fact that they give you a ton-o-power..yet basically a lot of “rope to accidentally hang yourself with” as the cliché goes. There are some tricks and such for C/C++ that work, but should be used carefully.

If statements are very common and often only deal with simple statements. If this, then assign this and so forth. If you have a simple if condition and want to assign some value or another based upon that condition, then you can use this instead:

( (conditional) ? (true value) : (false value) )

Basically, if the first parameter (which MUST be a boolean result, 0 or 1—true or false), resolves to be true, then the 2nd parameter is returned. If the result is false, then the 3rd parameter is returned.

Another actual useful command is the pre and post incrementor. If you want to increment or decriment a variable by just one, simply add the ++ or -- to the variable. “x++” or “q--“ are perfect examples.

LOGIC

2.1 LOGIC

The question of programming starts with the question of logic. All pointy ears aside; the idea of logic is not some complex philisophical concept that rules the daily life... logic is the question of the obvious, measurable things in front of you. The "Duh!!" factor. Logic is holding an apple and saying, "I am holding an apple." Philosophy is holding an apple and saying "This apple dreams of pies." So, the first lesson is… programming is only dealing with what is measureable. So lets get down to measure.

2.2 Truth or Dare

What is true? What is false? You can’t get away with any escapism when answering this question for computers. What is true is true and what is false is false, and understanding how this works is VERY important. The complexity comes when you are trying to chain together a number of questions together to get the answer that you want.

2.3 IF I only….

The first logic idea is the decision gate. This is the most useful and most common of all logical questions. IF some question is true, I want this to happen. But it can get more complex than that…. IF this is true, then I want this to happen, in all other cases, I want that to happen. To even more compilicate things, you can chain together a bunch of statements.

Here’s an example.. the hardest question in the Universe: Where togoto for lunch.

IF ( I have $20 in my pocket )
I will goto The Olive Garden
ELSE IF ( I have less than $20 but more than $10 )
I will goto Village Inn
ELSE IF ( I have less than $10 but more than $7 )
I will goto Subway
ELSE IF ( I have less than $7 but more than $2 )
I will goto Jack in the box
ELSE in all other cases…
I will go home and eat Peanut butter and jelly

2.4 Running in Circles (that’s…looping)

Looping is another very commong logical construct. In the most basic level, all loops have three parts: The beginning condition, the repeated portion and the exit condition. The beginning condition sets the starting values, and important part since your “exit condition” usually depends on what is set in the beginning. The repeated portion is one or many things that are done...repeatedly...every time the loop is executed. The exit condition is evaluated every time the loop is run to see if the conditions have changed to allow the loop to be finished.

There are some common mistakes in looping. Looping without a proper exit condition can effectivly go on without end. This would effectivly “crash” most programs, or even worse, eat up available memory until there’s nothing left. However, most operating systems now detect “runaway” programs and let you kill them before they do any damage.

2.5 The FOR loop

A “For” loop is one basic way to run through a series of numbers. In fact..to even do a for loop you MUST have an integer value to run through. So..basically, you can run a for loop from any point to any point that can fit in the integer variable you declair. “For 1 to 1000 do this” or “For –100 to +100 do that” and so forth.

Lets start out with a looping example. Twenty-five kittens are sitting in a room. One kitten has 25 fuzzy mice and wants to share with the other kittens.

For every fuzzy mice do
Give one kitten one mouse
Move to the next mouse

So…if these mice were numbered… the first mouse would be 1..next mouse would be 2…and so forth.

Now what if this kitten changed her mind and wanted her fuzzy mice back?

For every kitten do
Take one fuzzy mice
Move to the next kitten.

The trick with For loops is that the begginning and ending conditions are built right into the statement. We are moveing from one number to another number, and will not stop until we’re done.

2.6 While Loops

While loops come in two different flavors; the “do…while” loop that always runs once, or the “while” loop. Both of these are hinged on an exit condition. However, unlike “For” loops, while loops require that you set both the beginning and ending condition yourself, and isn’t taken care of by the loop itself. If you do not fulfil either condition you can have the loop that will never execute, or executes the wrong number of times, or never ends.

So our little kitten wants to make her own fuzzy mice. She knows how to make one, but doesn’t know how many she can make until she goes through all the materials and use it to make each mouse.

Beginning condition: Set out fuzzy mouse materials

LOOP: while fuzzy mouse materials last do the following
Collect materials to make one fuzzy mouse.
Make the fuzzy mouse
Move on to the next mouse

Ending condition: no more materials to make a full fuzzy mouse.

So, this loop will only end until the materials ran out. Well…what if we wanted to only work for four hours.


Beginning condition: Set out fuzzy mouse materials

LOOP: while fuzzy mouse materials last do the following AND working time is less than four hours
Collect materials to make one fuzzy mouse.
Make the fuzzy mouse
Move on to the next mouse

Ending condition: no more materials to make a full fuzzy mouse AND working time is less than four hours.

Only difference this time is that there is a double ending condition. Both have to be true in order to exit the loop.

2.7 Sentinel Value

One idea that is very old is the use of a “Sentinel” value. This is some sort of number, index, or condition that is unique enough to never happen in a normal case, and can be used as an “ending condition” for loops. Say, the use of “-1” when you’re dealing with the number of inventory, where you’ll never have (except in Enron-run companies) negative inventory.

3.0 Knowing the Truth and the False of it

One complex idea with logic is knowing when something is true and when something is false. This…may seem oddly obvious, but it is a bit more than that. When you have one statement, it’s either true or false. “The sky is blue” is a true or false statement statement. Its when you combine statements that you get into trouble. So how do you combine logical True/False questions?

3.1 AND, OR, NOT, and sometimes eXclusive OR

Your logical AND requires that both statements to be true for the whole combined statement to be true. “If (a AND b) then” will only execute if both “a” is true and “b” is true. In C++ and java, the AND is represented as two andpersand (&&). Pascal and Basic actually use the word “and” instead.

Your logical OR only requires that one or the other be true for the whole statement to be true. “If (a OR b) then” will execute if either “a” or “b” is true. In C++ and java, the OR is represented by two verticle bars (). Pascal and Basic, again, uses the word “OR.”

The NOT value is used to make a statement opposite of what it really is. If a statement is True, then NOT will make it false. This is very useful when trying to make your programs more readable. “while Not( boolHavingProblems) do” makes it very clear what you are trying to say.

Exclusive Or (often called “XOR”) is a different version of OR, in that if both values are the same (doesn’t matter if they are both true or both false) the result is false. That’s why its “exclusive.” “if (a XOR b) then” will only execute if either “a” or “b” is false and the other is true.

3.2 Truth Tables

A common logical exercise is to list a Truth Table. This is useful to figure out what can or can not happen in your software. Understanding the patterns in a truth table is very important. The way you read it is, each variable is assigned every possible combination of “True” and “False” to find out what the resutls will be.

A AND B Makes
T T T
T F F
F T F
F F F

A OR B Makes
T T T
T F T
F T T
F F F

NOT A Makes
T F
F T

A XOR B Makes
T T F
T F T
F T T
F F F

Now try to combine things into a complex set of conditions

A AND (B OR C) [what B OR C MAKES] MAKES
T (T T) T T
T (T F) T T
T (F T) T T
T (F F) F F
F (T T) T F
F (T F) T F
F (F T) T F
F (F F) F F

3.3 Translating True and False

True and false to a computer is basically either on or off, 1 or 0. The number 1 is assumed to be True, and the number 0 is assumbed to be False. In many languages it is possible to play tricks with this assumption by doing some simple math tricks. Two numbers are equal if you subtract them out and it becomes zero. SO if they are zero, the value can be resolved as a boolean expression, testing for “False.”

Variable Memory

1.1 Variable Memory

Its really hard to start at any one spot, but a very important concept to understand in programmig beyond logic is the idea of how to use the computer’s memory. In order to do anything in any program, you will eventually have to reserve memory on the computer to be used by your program. This is done by declairing “Variables.” Variables as the name would suggest are things that stand for…things. Just like your old algrebra, when you would put in the letter “X” to stand for any number, you can declair a variable in your program to stand for any number.

What this is doing is telling the computer to reserve a set of memory for the programs uses of a certain size. The actual location of that memory is purly random, and once you actually declair it could contain any sort of information. This is called “Ininitialized Memory”…basically…just because you reserve that bit of memory doesn’t mean that some other program didn’t just release that memory, and it could have a bit of information still sitting there. Because of this, the standard practice is to ALWAYS put an initializing value in a variable..no matter what the variable is or might end up doing. It just makes sure that the only information you are using is stuff that you put there

1.2 Counting in Computer Land.

It is important to understand that this reserved bit of memory is placed in a random spot in memory. That spot’s size depends on the programming language you are using or what compiler you are using. It all is because of how computer’s count: in 2’s. Just picture that you can count, but only as high as the number of fingers you have. If you just use one finger for one number, then obviously you’re only gonna make it to 10. However…if you use a special “code” you can make your right hand count as “1’s” (each finger is worth 1) and your left hand count as “10’s” (each finger is worth 10) and suddenly, you can count to 99. Try it out:

Computers count using just groups of 1’s and 0’s. This is usually in groups of eight (1 byte) but lets look at the first four bits.

0000 = 0
0001 = 1
0010 = 2
0011 = 3
0100 = 4
0101 = 5
0110 = 6
0111 = 7
1000 = 8
1001 = 9
1010 = 10
1011 = 11
1100 = 12
1101 = 13
1110 = 14
1111 = 15

Zero through fifteen. Now..lets get even trickier. Lets reduce that down to one digit each…so the same table:

0000 = 0
0001 = 1
0010 = 2
0011 = 3
0100 = 4
0101 = 5
0110 = 6
0111 = 7
1000 = 8
1001 = 9
1010 = A
1011 = B
1100 = C
1101 = D
1110 = E
1111 = F

So, by this table..if I counted to E, I really mean 14. Now lets put two together; F2 would be worth 242…that’s 16 * 15 + 2 (the position that “F” stands is worth 16 for every one…so that’s 16 * 15). CA would then be worth 202, being 16 * 12 + 10. This is called Base 16 counting, or Hexadecimal.

Here’s how it works: No matter what base you are in..if its base 10 (what we normally count in), base 2 (that computers us) you can find out what the value is from the position the digit is in. So if it’s base 16, the first position is worth 16^0. The second position is worth 16^2. The third position is worth 16^3, and so on. So, 931 in base 16 is worth (16^2*9) + (16^1*3) + (16^0*1) or 2353.

But what happens if you run out of fingers? If you only have four bites to count with, what happens if you ned to count to 16 or 17? The short answer is…you don’t. If you go beyond the bounds of the memory you are using, it encounter either a overflow or an underflow. For instance, if you add one to F (or 1111) that is 15, it will become 0 (0000). Or if you subtract one from 0 (0000) it will become F (or 1111). However, in many compilers, these over or underflows will be captured and return an error.

1.3 Other types of Encoding

A normal 16-bit integer is between –32,678 and 32,767. This is done by actually using the first 15 bits for counting, then the last bit as the “Signed” bit. This tells the compiler if the number is either positive or negative. So what if you don’t need to count to negative numbers? You can then use an “unsigned” integer, counting from 0 to 65,535—doubling your range.

Floating-point numbers are trickier, because they are stored in a different way. No matter what the size of the floating-point number, it is divided into three parts: the signed bit (for positive or negative value), the base number and the mantessa. So the result is that similar to scientific notation: -1 * 153 * 10^2, where the 153, -1 and 2 getting stored. This can cause problems when you dealing with rounding. Try declairing 2 variables, and in one just put the number 0.33. In the other, put the number 100, but divide it by 3. Print these two numbers out. This is a direct reason because of how floating-point numbers are stored. There are ways around this, but that can wait until later.

1.4 Flavors of Memory

So what are types of memory? There are different types with different compilers. Here is one example.

There are others, but this is just one example of one language in one compiler. Therefore…its best to check the compiler you are using. The important idea to walk away with is that when you create variables you have limits. Of course, this means that you will need to know what you will be using first (are you just counting from 1-10? Then a Shortint would be good. Are you counting population of California? Maybe a Longint would be better) then check your compiler’s available types for what to use.

1.5 Bloatware verses Just Enough

So why use a “Shortint” at all? If I can only count between –128 and 127 with that one, so what good is it? Why not use a Longint for everything? This argument is very commong and the result is more often than not, to just use the biggest memory available. The result is what is commonly known as “Bloatware”; software that takes up tons of memory just because it can. The consequences of having huge available memory is that programs are getting created to fill that memeory…if it needs it or not. So if you can use a short int….you should. For no other reason than to be efficient. Fast, efficient and compact means a stronger more useful program.

Kitty Programming Tutorial

0.0 Programming

Programming is the same no matter what language you use. There are gives and takes in all languages, and even with who wrote each individual version of each language. The harsh reality of the matter is that marketers who make choices based upon popularity and which company had the flashiest add in some magazine do most descisions made about technology. For the purposes of this kitty tutorial…we’ll just start out with basic ideas.

0.1 Abstract Concepts

One problem with programming is that you do have to understand some fundamental parts about the computer. Not enough to build one, but a general idea so you can see where the rest of this information is coming from.

Just think in terms of computers…they are the most snik-pikky types that will do EXACTLY what you tell them to do, no matter if it makes any sence or not. Just picture it like an anal retentive old man who has to have everything organized in a specific way and has a desk full of things sitting at right angles.

In terms of programing, computers just have input devices (keyboard, communications ports, etc), storage devices (hard drive, USB keys, etc), Central Processing Unit (the brain), and output devices (printer, screen). For the most part, this is the only parts of the computer we’ll be concerned about.

Now..the computer is very picky about how things work. The “old man’s” desk is organized into different sections. Everything is organized into specific sizes and areas. This is just like how memory is used in a computer. All the action takes place between the CPU (that does math, transforms things, etc) and the active memory (which is a combination of “RAM” and your hard drives). The memory itself is sectioned off into different segments, where part is reserved for “Operating System” only, other parts for “Addresses” and so forth. If you try to mess with these reserved spots, the computer will not work right—our snik-pikkety old man will get upset. And the section of that memory that we are allowed to use, must be sectioned off in a specific way in order to keep the old man happy.

These are really abstract ways to put this, however should make some of the rest of this information make more sence.