Part 5: Intro to Pointers
While it is possible for a program to access information stored in a computer's memory through the use of a variable, there is another method commonly used in C programming. A variable type called a "pointer", which is a pointer to memory address, is how this type of access is done. Instead of a variable pointing to information stored in the computer's memory, the pointer variable points to an actual location in memory. Pointers are one of the most confusing parts of the C programming language, they are also one of the most powerful. Repeated study of the topic does not always result in full comprehension, and can be aggravating at best. Use of pointers is possible without full comprehension, but continued use will result in very complex errors, usually hidden deep within the program's algorithms.
To put it simply, pointers are variables that store, not a value, but the location in memory which contains
data for your program's use. For example the integer MyInt holds the value 7 in a location in memory, location
0007 F7EA. You would then assign the memory location itself to a pointer variable named MyInt_p. The underscore
and p at the end of the variable name are not required, but make it easier to understand that variable is a
pointer when reading through your program. Because they hold only memory locations, pointers are usually the
same size, normally a long integer, but there are as many different types of pointers as there are types of
other variables. This will be discussed in more detail in a future article detailing pointer arithmetic.
Pointers are declared using an asterisk, *, called the indirection or dereference operator, defining the variable as a memory pointer to the declared variable type. The dereference operator is also used with pointers to access the value stored at the pointer's defined memory location. They are assigned the memory location of a variable of their specific type using the ampersand, &, commonly called the redirection modifier or "address-of" operator. Here is an example pointer declaration:
int MyInt, *MyInt_p;
This example declares an integer variable named MyInt and an integer pointer variable named MyInt_p. Even though it is
on the integer assignment line, the pointer is not necessarily the size of an integer because it holds the memory location
of an integer and not an integer value itself. To place the memory address of the variable into the pointer, you would use
the "address-of" operator in a statement like this:
MyInt_p = &MyInt;
What this statement does is tells the computer to store, not the actual value of the MyInt variable,
but the memory address of the variable, to the memory pointer MyInt_p.
One of the easiest ways to learn and fully understand pointers is to visualize a simple example where they would be required and understand why a pointer is required. Since pointers are so powerful, there are very few simple examples, so complex algorithms are usually used to demonstrate their usage. This usually hides the requirement of the pointer and its purpose deeply within the convolutions of the algorithm example itself. A simple algorithm will allow you to see the pointer in use, and help you understand why a pointer is used in that manner, without the complexity of the example algorithm distracting you from what you are trying to comprehend.
Suppose you had a program which required exchanging integer variables with each other repeatedly throughout the program's execution. It would be best to create a function to do this since it is the same task repeated over and over. If you were only exchanging the same two integers, you could make them global variables, accessible by all functions in the program, then exchange them within a function like this:
void Swap(void)
{
int temp;
temp = a;
a = b;
b = temp;
}
However, what if the two integers you were exchanging were different variables each time? Would you write a
Swap() function for each pair of variables? While this would work, it would be very inefficient,
and one of the main design purposes of structured programming is efficiency in code. Since a function can only
return one value, you can't store your variables in local variables, swap them and then return them both.
What if there was a way to have the function actually change the information in the specified memory locations
of any pair of variables you send to it as arguments? This is exactly what pointers allow, and one of their main
uses. Instead of sending the value of the variable to your Swap() function as arguments, you can use
the "address-of" operator and send the memory addresses of any pair of variables, then the function will change
the data within the memory locations. Here is an example function:
void NewSwap(int *a_p, int *b_p)
{
int temp;
temp = *a_p;
*a_p = *b_p;
*b_p = temp;
}
When using pointers to exchange values, you must be sure to use the indirection operator so that you swap the values being pointed to and not the memory addresses contained in the pointers. When you call your function, be sure to use the "address-of" operator to send the address of the variable to the function and not the value stored in that variable. You would call this function using the "address-of" operators, which sends the memory addresses of the variables to the function and not the actual values. Now you can send the addresses of any two variables and the function will exchange the values stored in those variables like this example:
NewSwap(&a, &c);
Now when you use the variables a and c from this example, the values would be exchanged.
While pointers hold memory address, you can use them directly to access the values stored in those addresses. For example instead of displaying the integer value stored in the variable c with the first statement following, you can use the pointer to display it exactly the same by using the second statement.
printf("The value in variable c is %d.\n", c);
printf("The value in variable c is %d.\n", *c_p);
In the second statement, the value used in place of the %d place holder in the printf()
function is the value located at the memory address stored in the pointer c_p. While this may have been
confusing before, you should understand now that the indirection modifier before the pointer variable name tells the
program to look at that memory address to get the value stored at that address.
While there are other ways available to swap any two variables, using pointers is one of the most efficient, and hopefully this simple example helps to explain pointers in a very easy to understand manner. Always remember that pointer variables can only hold memory addresses, using the indirection modifier you can access the value at a memory address, and using the "address-of" operator you can get the address of a variable. Like everything in C programming, practicing using pointers is the best way to fully understand them, but simple algorithm examples like this one hopefully help make the basic process easier to grasp so that the use of pointers themselves become apparent and the comprehension of their use becomes easier.

