In this lesson, I will teach you about pointers. Pointers, simply put, are small places in memory that point to another location in memory, usually a variable. Why would one want to do that? Well, the answer is you're getting ahead of yourself! I will certainly discuss the uses for pointers later, but for now, we'll learn how to use 'em. In order to create a usable pointer, you must first allocate some space in memory for the pointer to point to. You already know how to do this; declaring a variable is all you really need to do, but there are other options which I'll examine later. So you must first declare a variable, and then you must declare a pointer and tell it what data type it will point to. It is essentially identical to creating a normal variable, except you place an asterik (*) in between the variable and the data type. The data type will, of course, be what the pointer is capable of referencing. Anything else will give you gibberish when you invoke the pointer. Here's the process I just described in action.
int a; int * pointer_to_a;
So you've declared the pointer and the variable that it'll point to, but the pointer is NOT pointing to your variable yet. In order to do that, you have to assign the pointer to the variable's location in memory. However do you do that, you ask? Simple! The ampersand (&) is a wildcard character in C++ that you can place in front of any variable to make it return its location in memory rather than what it is storing.
However, there is a caveat that makes things a little confusing at times. The asterik used to create the pointer is also a wildcard that you must use at certain times. As a general rule of thumb, whenever you want to grab the value that the pointer is pointing to, you must place the asterik before the pointer's name. This is called dereferencing the pointer: grabbing the value it is pointing to rather than the memory location it is storing. If you want to get the location in memory of the value it is pointing to (which is technically the information it is storing), you must use the pointer's name by itself. Lastly, you can invoke the pointer's location in memory with the ampersand. All of that may sound confusing, but it is pretty consistent. It is important that you get a strong grasp of how this all works, though, because it is here that people begin to flounder when using C++ (many important concepts use these tenets almost exclusively). But I digress, now I'll make the pointer point to the variable.
pointer_to_a = &a;
Now, I'll just give you some examples of all of that jargon I discussed in the previous paragraphs.
cout << "a's value:" << a << endl; cout << "a's location in memory:" << &a << endl; cout << "pointer_to_a's value: " << pointer_to_a << endl; cout << "pointer_to_a's location in memory:" << &pointer_to_a << endl; cout << "the value that pointer_to_a points to:" << *pointer_to_a << endl;
As you can see, &a and pointer_to_a are identical; &a is the variable a's location in membory, which is what pointer_to_a is storing. You can also get pointer_to_a's location in memory with the ampersand(&) as I did, because while it is a pointer, it still needs its own little place in memory to store the location in memory of the variable it is pointing to.
One last piece of information pertains to what you're allowed to do to pointers. When using the asterik -- the value that pointer_to_a points to -- you can assign it values like any other variable. However, under normal circumstances (I will certainly note exceptions when the time is right) any changes you make to it will be reflected on the variable that it points to. Here's an example using a and pointer_to_a.
a = 5; *pointer_to_a = 3;
At first, variable a will equal 5. After the second line executes, though, the value of a will change to 3.
One last facet of pointers is how to set a pointer to "empty" mode. This is done by setting it equal to the word NULL. NULL is actually a variable that is implicitly defined in C++, and it allows you to identify whether a pointer is defined with a valid memory location or not. Most functions that work with pointers return NULL on failure, so you can check to see if a pointer equals NULL to decide whether or not to use it.
int holder;
if(pointer_to_a != NULL)
{
holder = *pointer_to_a;
*pointer_to_a = NULL;
}
As you can see, you can either check for NULL or assign it.
Learn this lesson well, as is the foundation of a great deal of C++'s functionality.