Sunday, December 21, 2008

Week 2, Day 2

Haven't been in a programming mood as of late... but I pushed myself to do this one anyway after taking a few days off.

Today's "Class"
References. A reference are just a pseudonym of a variable you already have declared. They cannot be null... EVER. Or rather, they SHOULD not ever be null or referencing a variable that does not exist. References are fantastic, enabling you to use many of the useful features of pointers, WITHOUT the extra syntax and the extra difficulty of doing so. Here is a simple definition of a reference:
...
int myVariable = 5;
int & rMyVariable = myVariable;
...


Now, whether you use the variable name "myVariable" or "rMyVariable", the same piece of data is utilized. That might not seem like a very useful thing to do, and in that little snippet... it wouldn't be. The power behind references is the ability to pass the entire variable into a function and let the function actually edit the variable. Here is a sample program that does just this:
// Example of how to use references in a function
#include <iostream>

using namespace std;

void swapValues( int & x, int & y );

int main()
{
    int x = 15, y = 33;
    cout << "x: " <<
    swapValues( x, y );
    cout << "x: " <<>
    return 0;
}

void swapValues( int & rX, int & rY )
{
    int temp;
   
    cout << "swapping...\n";
    temp = rX;
    rX = rY;
    rY = temp;
}


If you do compile that guy and run it, you should see exactly what you THINK you should see. The restrictions for references are as follows: (1) you MUST initialize the reference (since you cannot have a reference that is null) and (2) you CANNOT reassign a reference. References should be used in place of pointers when at al possible. You can obviously reference ANY type of variable or any object, just like with pointers.
References also have the added bonus of reducing memory usage and speeds up the program slightly. This doesn't matter too very much when you are just passing in some number, but using user defined objects with references is a very good idea.

Summary and Workshop
Summary was quick and to the point. Reviewed the essentials of references. The exercises were rather tedious to me. I actually skipped a few since I just wasn't in the mood and I knew the topic pretty well from the chapter. I may finish up the exercises another day, not sure yet. Either way, the exercises were very easy and didn't really make me think any.

Sunday, December 14, 2008

Week 2, Day 1

All about the Pointers.

Today's "Class"
Today featured a lengthy introduction to pointers and an explanation of how they actually function. Apparently pointers are one of the more difficult concepts to grasp for new C++ programmers. I can imagine. It isn't that the concept is confusing in theory, it is the practice that is a bit bothersome for me. To a degree, I understand WHY pointers are valuable. Being able to store variables on the "free store" of the RAM, safely tucked awa... int * pMyVariable = 0...y for use by any functions, is like creating SUPER GLOBAL variables. And yet you still get to control how much access is given to these variables by carefully using objects and the const keywoard to protect writing to the variable (and / or the pointer).
What is difficult to grasp is exactly WHY you would need to use pointers. The book says by the end of the "week" the reader will have a good grasp of what to use pointers for and whatnot. I guess I'll have to take it on faith then.

pointers - What are they?
pointers hold an address of a variable. Every variable in C++ is stored on the RAM. Well, this should be true of any programming language really. Anyway, so in C++ when you have variables on the RAM you can actually retrieve it's address in a fairly straightforward manner. Example code snippet to see an address of a variable:
...
int myVariable = 5;
cout << "myVariable is located at: " << &myVariable;
...

This little bit of code (when placed in a properly set up program), will print the address of the variable you declared the line above. It will not print 5. Instead it will print a hexidecimal (I think) code of WHERE the value for myVariable is PHYSICALLY stored on your RAM. Run this program a dozen times and you could get a dozen different values. Or they could all be the same, it just depends on your OS and your physical hardware.
So, like I said... a pointer STORES the address of a variable. Which means I have not shown you a pointer yet. You define a pointer in a very similar fashion to defining a variable. Let's redo the code snippet above to actually use a pointer shall we?
...
int myVariable = 5;
int * pMyVariable = &myVariable;
cout << "myVariable is located at: " << pMyVariable;
...

As you can see, it is pretty easy, like anything else in C++ once you understand the concepts. Now, there are three VERY important things to pay attention to when declaring a pointer.
(1) a pointer needs to be defined as the exact same type of variable as what it is pointing at. We were pointing to an int, so the pointer had to be an int as well.
(2) don't forget the asterisk. That is what is letting the compiler know this is a pointer.
(3) either point the pointer to an address of a variable, define a new variable for the pointer, or POINT IT AT NULL (... int * pMyVariable = 0; ...). If you have the pointer "dangling" or "wild" or "stray" it could cause some rather unpleasant bugs in your program that will be a nightmare to find in the future.

What's the Point
To understand why you need to be able to use pointers in the first place, you need to understand the basic structure of how computers store information in the RAM. Go get a book, as that is a topic and a half. You don't need to know the mechanical function of RAM or the technical specs, but you do need to know how the RAM houses information in different "areas" and what happens to each area in C++ while the program functions. I have said it before, and I will say it again... if you want to actually learn C++, go beyond just reading me review what I have learned... buy a book or enroll in a class. The benefits of being taught correctly the first time through is muy bien.

Pointers can access the data too!
So, pointers also can access the data of the variable they point to. It could be slightly confusing I guess, but with practice it doesn't seem to bother me anymore. The example we wrote before... let's change the variable data and see how it works eh?
...
int myVariable = 5;
int * pMyVariable = &myVariable;

cout << "myVariable, located at " << pMyVariable

*pMyVariable = 10;
cout << "myVariable, located at " << pMyVariable
...

Look confusing at all? The asterisk has dual function. When you are defining the pointer, it informs the compiler that this variable contains an address. When you are using it any other time in your code, it says that you are accessing the VALUE stored at the address the pointer points to.
So, in the above example:
pMyVariable would equal some hexidecimal address
*pMyVariable starts out as 5, and then we change it to 10. *pMyVariable is identical to myVariable in this example. When one changes, the other changes as well. They are just different labels for the same data.

Practical Uses of pointers
I don't have a full grasp on what the usages are yet, that will come tomorrow and in the following days, but I can give an overview.
pointers store data on the "free store" part of the RAM, which means after the function is over, the data is still there (unless you explicitely delete it). Of course, you have to make sure you can still ACCESS that data... otherwise you have a memory leak. The data will still reside in the address the pointer points to, BUT the pointer variable itself is stored in the "stack" of the function, so after it is done it will be GONE, unless you have the pointer somewhere other than the function and you are passing it into the function in the first place.
The one example the book gave (and the author didn't have me make this so I am not sure how exactly it works yet), is a word processor. A dialog box needs to have access to the document, but once the dialog box finishes it's task... we don't want the document disappearing. Makes sense... but why not just use an object for the document? I don't know, I'm sure there are reasons.

pointers can also CREATE a variable. The example we listed before, here is yet another version of it:
...
int * pMyVariable = new int (5);
cout << "pMyVariable points to: " << pMyVariable
cout << "*pMyVariable is: " << *pMyVariable << "\n";
...

This should demonstrate what I am talking about. You can of course use pointers for objects as well. It would be the same as before, but instead of type int, you would use your class name. To access functions from the pointer for that object... you would do something like this:
...
fish * pGoldfish = new fish;
cout << "pGoldfish is a fish with the default weight of " << pGoldfish->GetWeight() << " lbs.\n";
pGoldfish->SetWeight(10);
cout << "pGoldfish is now 10 lbs, see: " << pGoldfish->GetWeight() << " lbs.\n";
...

Obviously, you would need to have a class named "fish" with the functions "GetWeight()" and "SetWeight( int weight )". And having a default weight in the constructor would be a very good thing if you are going to copy and paste that little snippet above. The "->" accesses functions of an object through a pointer. Notice that you don't need an asterisk to get into the functions.

Summary and Workshop
That is just about all they covered. The end of the chapter demonstrated a program that seperates a string into words. The program obviously used pointers to do a lot of brunt work and showed how flexible they are when traversing functions. The exercises were very, very easy. Just making sure you understood how to use pointers really.

Saturday, December 13, 2008

Week 1, in review

So, I wrapped up one week of the book... a third of the way there. I treated myself to a couple of days of light duty. The book had a few pages of review and I covered those. Basically, it was a single program that did stuff with rectangles. It could draw them out in ASCII-test, calculate area or perimeter, allows you to change the height and width, and of course quit the program.
Nothing too difficult. Although there was an error in the code in the book that took me a bit to figure out. I still don't know why it was in there... I knew it didn't belong there and so I removed it and the program worked like a champ. Had a few typos here or there, but the compiler helped me hunt those little guys down.
Now I can make a very simple, text-only program that runs in the terminal in linux. I could write a program for an early 90's library computer now! Score! [/sarcasm]

Thursday, December 11, 2008

Week 1, Day 7

goto, while loops, for loops, do...while loops, and switch expressions. Pretty basic program flow parts of basically any programming language (ok, so the last two are not in all the languages I have learned so far... but still).

Today's "Class"
Today's chapter was all about controlling the flow of the program with loops and another condition branch tool.

goto
Basically... after showing how to do it, the book said to never use it. It makes code rather confusing. It has it's very rare uses, but apparently the author has only had to use it ONCE in his entire C++ career. If you feel you absolutely need to use it, you should be more capable at C++ than this blog will probably EVER teach you... so I won't bother going any further on it.

while loops
Very basic and straight forward. While the condition is true, the code is executed. Example:
int i = 0;
while( i < 10 )
{
i++;
cout << "i: " << i << endl;
}


That little code will just print "1", "2", "3", ... all the way down to "10". Nothing too complicated. Obviously, if the condition is false to begin with, the code is not ran at all. Be careful not to make a never ending loop unless you have a way out of it.
Speaking of a way out of a never ending loop... the break; command will exit a loop. The continue; command will restart the current loop at the beginning of the loop (skipping whatever is after the command). Apparently, those are suppose to be used sparingly... so as to make your code more easily read. Good to know that you can do that in your code if you come across something that needs it.

do...while loops
If you would like to create a while loop that for sure executes at least once, use a do...while. It is identical to a while loop, with the simple exception that it tests for while AFTER the code block is ran and not before it is ran. Example:
int tooLarge = 15;
do
{
tooLarge++;
cout << "tooLarge: " << tooLarge << endl;
} while(tooLarge < 10);


If this was a while loop, it would never print anything, but the do...while loop executes once and then figures out that it shouldn't loop because the condition is not met. Obviously has some usefulness in it... I can't think of a good example at the moment though. Sorry. Moving on then...

for loops
While loops are fantastic... but sometimes they are not really the right tool for the job. For instance, the code I gave as an example earlier could be done much better with a for loop. Like this:
for( i=0; i<10; i++ )
cout << "i: " << i << endl;


Nice and tidy eh? for loops have an expression, a condition, and another expression. Usually you initialize your variable in the first expression and the last expression does some sort of incrementing or decrementing. However, the chapter had me write several different programs that used all sorts of expressions in there. You can even just write a condition... but then it is just a differently labeled while loop. One of the last examples was a "forever" loop, which is a identical to a while loop that had a condition of "true". However, I love what some programmers put down to create a "forever" loop:
#define EVER ;;
....
for(EVER)
{
....
}


That has a degree of elegance and readability I love. #define EVER ;; tells the compiler that whenever it sees "EVER" in the code, replace it with the text ";;". Thus, the "forever" loop is correctly written for( ; ; ){ ... } as in a blank expression, a blank condition, and a blank expression... or a loop that can never end.

switch expressions
Instead of doing massive if...else branches, you could use switch... case.... default... expressions. You provide a variable, and then write down the different "cases" (if the value equals this... do this...). You can (and should) specify a default, if for no other reason than to debug. Here is a sample switch expression:
cin >> choice;
switch( choice )
{
case (1): cout << "you chose option one.";
break;
case (2): cout << "you chose option two.";
break;
default: cout << "that wasn't an option!";
break;
}


The break; commands are important. If you don't have them in there it will execute several commands (give it a try, it was interesting to see what happens). Obviously this is not as powerful as an if...else, but if you can use it, it is much tidier.

Summary and Workshop
Thus ended another chapter with the common summary. Exercises where ok, but I had the concept down WELL before I even finished the chapter. The chapter really seemed to drag on for me. But, that is simply because I have been using these sort of program flow loops and expressions since I was a sophmore in high school (used to program those graphic calculators for math class... surprisingly that became rather a useful primer as I went through life...).

Wednesday, December 10, 2008

Week 1, Day 6

Hey, something completely new to me! Score. Finally I get into some meat.

Today's "Class"
Today was all about Classes and objects.

I have never done object oriented programming (in the strictest sense at least). This chapter really made the five slow days behind it pay off (well... start to pay off). I actually learned some new concepts and my brain is busy absorbing the new information and what it means for my code in other languages. So, I am pretty happy obviously.

Classes are the new "types" of variables the book talked about in the past. I think this is a misnomer personally. You still are restricted to the limitations of the pre-existing variable types in C++. I was hoping (and still hold out some hope that this is included in C++) that you could have an array, or even better, a hash. How I have become so dependent on arrays and hashes.... PHP has spoiled me I tell you! So, while not able to create a new type of variable in the sense I wanted, classes are still very useful. Classes (and the individual objects of that class) are organized groups of data and functions. Here is a for instance:

Class: Car
Properties: Wheel Size, transmission speed, engine size, gas tank size, number of passengers, ...
Functions: Throttle engine, shift gear up, shift gear down, engage brakes, open door, ....

With all of the variables set up and the functions defined, you could easily create an instance of a "Car" by typing:
Car mySubaruImpreza;

Or, if you have the class constructor built, you could assign all of the specifications of the car right when you create it.

Honestly, writing a review of the chapter today would be like typing the entire thing. I'm not going to do that. So, instead, buy a book, check one out from the library, google C++ Classes, or whatever you usually do. This is one of those things you should learn from something more substantial than a blog designed to review one person's efforts toward learning how to program on Linux.

Summary and Workshop
The exercises again made me think. Probably because the whole Class thing is fairly new to me. The closest thing I have come to this is doing some OOP stuff in JavaScript. Oddly enough, it is actually pretty similar... but C++ takes it above and beyond the little I learned in JavaScript.
I made a few mistakes in my code as I worked on the proposed problem. I'm glad too... because every bug I made taught me a little about Class declarations and definitions that I had apparently not paid attention to during the chapter.

Tuesday, December 9, 2008

Week 1, Day 5

I had to fight paint fumes last night, so I escaped my workspace and let the headache subside. Finished the lesson up this morning.

Today's "Class"
Functions are pretty straight forward in C++. The one new piece of code, for me, is that you have to declare a "prototype" of the function. The prototype is just a quick line of code that tells the compiler what value your function returns, the function name, and the type of variables you pass into your function (as well as any default values FOR those variables).
Sample function prototype:
int rectangleArea ( int length, int width );
You could also write it:
int rectangleArea ( int, int );
Adding the extra values of variable names though helps in the debugging process (or so the book says). You can use different parameter names than the actual defined function though... so just label it something useful if you are going to add parameter names. To add default values you would have the prototype look something like this:
int rectangleArea ( int length, int width = 10 );
This means you COULD pass one argument when you call this function and it would assume the width was 10 in that case. Obviously, you cannot have a default value for length if it (a) comes before width in the prototype and definition and (b) width does not have a default value also.

You define a function in a fairly straightforward manner. You have a header to the function with the return type, function name, and parameter list (almost identical to the prototype, except that the parameters MUST have names in the function header and you can't add default values in the header).
Here is the rectangleArea function definition:
int rectangleArea ( int rectangleLength, int rectangleWidth )
{
return (rectangleLength * rectangleWidth);
}


Super easy right? Now the chapter went into some interesting details about what you can do with functions in C++.

Function Overloading
Because you have to define the return value and the variable types of the parameters... what happens when you pass in a float instead of an int. Yep, it creates an error. However, in C++ you CAN use identical function names as long as they return and / or accept different variable types. Like this:

int Double ( int );
float Double ( float );

int Double ( int x )
{
return (x * 2);
}

float Double ( float x )
{
return (x * 2);
}


This way, if you call the function Double with either an integer or a float it still returns the value you want it to. You don't need to have two differently named functions and then have to remember which function you needed to call. You can "overload" a function many, many times (say you want to double short, long, float, double, and maybe even some signed and unsigned variables as well...). The book did mention you have to be careful with doing something like this:

int Divide ( int x, int y = 2 );
int Divide ( int x );

int Divide ( int x, int y )
{
return (x / y);
}

int Divide ( int x )
{
return (x / 3);
}


As you can imagine, if you DO make this function call "Divide(myVariable)", the compiler won't know which function you actually want to call and will throw up an error.

Inline Functions
Another feature in C++ is the ability to add a function "inline" the code when it is called. This can give you some performance gain... but at a cost. Every time you call that function, it will add the entire function body into your code and thus take up more storage on the hard drive, CD, etc. The book recommended you only use inline functions when the function is one or two lines as larger functions tend to bloat your code and the performance is probably negated by the extra code size. How much of a benefit you get by doing inline functions... I know not. Maybe I should play around and do some benchmarking... as soon as I know how to benchmark C++ code at least.
Here is how you have a function inline. In the function prototype declaration, you simply add the keyword "inline" before the return type. Here is an example:
inline int Divide ( int x, int y );

Recursive Functions
You can have a function call itself... or you can have a function call another function, which happens to call the first funciton again...
Confusing? Perhaps, that wasn't the best explanation. The danger is if you don't have a condition to the function that is being recurringly called. If the function just continues to call itself indefinitely it will bloat your program in your RAM until it crashes.
Why would you want to use Recursive functions? The book had a couple of examples of ways to use recursive functions, but I don't see why you would need to do them with those examples. In PHP or PERL you could easily do a FOR loop and take care of their examples without adding more and more to the RAM. However the book did mention there are the occasional problems that recursive functions are an elegant answer for. When I find one, I will no doubt be happy I know how to do recursive functions (or at least know where to look up so I can remember... although the implementation is exactly what you think it is... you just call the function from within the same function or another called function...).

Summary and Workshop
In the exercises there were some "bug finding" programs where you had to figure out what was wrong. Some of the bugs are things I'm sure programmers do ALL THE TIME. Like accidentally typing a semicolon after function header (in the definition... not after the prototype, which is required). I caught myself doing that a few times... but I caught it write after I typed it, so it wasn't a big deal. If I wasn't paying too much attention though I could see that causing some irritation. One of the exercises was to do a recursive function that solved x to the power of n sort of math problems (like x squared... x ^ 8... etc). That one made me think. Took me back to middle school when we had to do that sort of stuff all the time. Or was that High School... *shrug* whatever, either way it was a while ago. I ended up getting it first try though, so at least I had that going for me.

Sunday, December 7, 2008

Week 1, Day 4

Another super easy lesson. Covered statements, expressions, operators, etc. Nothing groundbreaking. It is identical to PERL and PHP, and since I have programmed in both I could have easily passed up THIS chapter as well.
The only thing unique about this chapter was the exercises at the end... two of the tripped me up and made me think.

Today's "Class"
Not interested in putting down the majority of the chapter, as it is super basic for anyone with a background in either C, PERL, PHP, even Visual Basic to some extent.
One thing to note though, is the "static_cast( variableName )" from the lesson. This lets you convert an integer into a float (or whatever you have instead of "float", I would assume). This does NO good unless you actually do it BEFORE you need a decimal value though, otherwise it will just be an integer stored as a float.