• VARIABLES VS. POINTERS
    In any programming language Variables are declared, and a main memory (RAM) “Pocket” is reserved for each of them at a location defined by what is known as their “Address”. Is in this corresponding “Pocket” in memory for each Variable that its value is stored. This is because the computer has to be able to differentiate between values belonging to Variables and “Pockets” in main memory serve exactly this purpose. This way the existence of a Variable is determined by two things and two things only: a) its main memory “Address”, and b) its Value. In most of the so called “High-level” programming languages, we are allowed to access directly only the value of a Variable. In C/C++, however, we are able to access both the value and the main memory “Address” defining the main memory “Pocket” of a Variable. This additional degree of freedom is provided to us through the concept of “Pointers” with the assistance of a couple of special operators. In this respect, to access the value of a Variable suffices to make a direct reference to the name of the Variable, as in the example below:

    alternative

    In this example, we declared a Variable by the name “X” its Data-type being “integer” and initialised it by assigning to it the value “10”. This way we fulfil the two requirements (main memory “Address”, name “X” and Value “10”) and the Variable successfully starts its life in our program. The only command existing in the example above prints the Variable’s value on the screen by making a direct reference to its name as an “integer” Data-type Variable. On the other hand, we may want to access the Variable’s main memory “Address” instead, as in the example below:

    alternative

    The only command existing in this example is printing on the screen the “Address” of the Variable in main memory (if we “Run” the program again and again we will make a very interesting observation; we take a different main memory “Address” for the Variable with every time we “Run” the program). The medium through which we are now able to refer and retrieve the main memory “Address” of the Variable instead of its value is the “&” operator. This is the so called “Address-of” operator.

    In this respect, we can safely consider the Name of a Variable as representing in a meaningful way to us the main memory “Pocket” its value lies into (a human mnemonic).

    alternative

    Let us explain a bit further this statement. When we want to Declare a Variable in C/C++, we do it by initiating a Declaration Command similar to the following:

    alternative

    In reality we do two things by initiating this declaration statement: a) we reserve a “Pocket” in main memory, that is, now we have at our disposal a specific location in main memory, accessible through an “Address”, in which to store potential values, and b) by initialising the Variable to “10” we store in this “Pocket” that became available to us the value “10”. From this becomes apparent that the actual name of the Variable (in this case “X”) serves the only purpose of providing us with an easy mnemonic through which we can easily refer to an actual “Address” in main memory. That “Address” characterises a main memory “Pocket” capable of holding a value of the specific Data-type the Variable has been assigned (in this case “int”) in its declaration command. Is exactly this characteristic that makes possible the existence and the use of Pointers in the first place. We declare a Pointer and initialise it to a specific Variable, as shown below:

    alternative

    The first thing we need to notice is that to declare a Pointer we do it through using the “*” operator, the so called “Indirection” operator. Again, as in the previous example, we first reserve a “Pocket” in main memory for our Pointer (because a Point starts its life as a Variable), and then by initialising the Pointer to the “Address” of Variable “X” we store this “Address” as a value in the particular Pocket in main memory (is exactly at this point that the Pointer gains its Pointer status). In this case the human mnemonic for the “Pocket” in main memory holding as a value the main memory “Address” of Variable “X” is “PointerToVariable” (under the light of what discussed above a more appropriate and descriptive name would have been: “PointerToAMainMemoryPocketAddress”, but this name is too long and very inconvenient to use in a program).

    alternative

    So, in a Pointer we never have an actual value by definition, what we have is always a main memory “Address”. In our case we do not have “X” in Pointer “PointerToVariable”, we have the main memory “Address” of “X”. The truly remarkable thing with this is that we can now use and manipulate the value in “X” without actually referring to “X”.

  • VARIABLES & POINTERS
    It’s time now to put everything together and have a glance at the bigger picture. The three examples below represent exactly this bigger picture, where all the pieces of the puzzle connect together.

    A) Change a Variable’s value through a Pointer
    We first need to take a good look at the piece of code provided below:

    alternative

    alternative

    Download "ChangeAValue"

    Let’s take each command in turn and explain what it does. The command at line 12, prints on the screen the Variable’s “X” value (11). The command at line 13, prints on the screen Variable’s “X” main memory “Address” in Hexadecimal format (0018F800). The command at line 14, prints on the screen Variable’s “X” main memory “Address” in Decimal format (136352). The command at line 16, assigns Variable’s “X” main memory “Address” o the Pointer “PointerToVariable” (136352). The command at line 17, prints on the screen the Pointer’s value (that is, Variable’s “X” main memory “Address” in Decimal format) (136352). The command at line 18 is the single most important command of all, through this command we assign the value “21” to the Pointer. The tricky thing now is that a Pointer, by definition, can hold only main memory “Addresses” and the value “21” is not a main memory address, rather, is a mere integer value. For this reason we add in front of the Pointer name the “Indirection” operator, and is now like saying: “I’m not assigning the value to the Pointer itself, I’m assigning the value to the thing the Pointer is pointing at...”, this operation is called “Dereferencing”. During execution, the situation is acknowledged and to be resolved the mere integer value assigned to the Pointer is stored in the main memory “Address” the Pointer holds. Effectively, this means that the mere integer value assigned to the Pointer is now stored into the main memory “Address” represented by Variable “X”. So, now Variable “X” possesses the value “21”, since “11” has been overwritten and lost. The remaining two commands just print again on the screen the main memory “Address”, in Hexadecimal and Decimal format respectively, for confirming that even through the main memory “Address” we still refer to the original “X” Variable. It is through this exact mechanism that all Pointers perform their magic.

    B) Read a Variable’s value through a Pointer
    We first need to take a good look at the piece of code provided below:

    alternative

    alternative

    Download "ReadAValue"

    Let’s again take each command in turn and explain what it does. This time the one command we need to focus on is the one at line 18. The logic behind the formation of the command is this: A Pointer holds the main memory “Address” of a Variable. To access the value in this main memory “Address” we need to “Dereference” the Pointer by using the “Indirection” operator “*”. Now the Pointer continues to hold the main memory “Address” of the Variable but this time “Points” to the value of this Variable and so can access it. As a result, the command prints the Variable’s value on the screen. The same value, of course, remains accessible through a direct reference to the Variable itself (commands at lines: 21, 22, and 23).

    C) Assign a Variable’s value to another Variable through a Pointer
    We first need to take a good look at the piece of code provided below:

    alternative

    alternative

    Download "AssignAValue"

    As before, let’s take each command in turn and explain what it does. In this piece of code the command at line 28 is the one making the trick. The Pointer, through the “Indirection” operator “*” accesses the value of the Variable and copies it into the new Variable. After execution of this command the second Variable possesses the same value as the first.


  • POINTERS & FUNCTIONS
    One of the most important benefits from learning how to cope with Pointers is that if we pass a Pointer to a function, the function can manipulate the Variable the Pointer “points” at. It is very well known that if in C/C++ we call a function, then all the arguments are copied to local to the function Variables that are declared in the parameter list (in the brackets next to the function’s name). Since these Variables are local to the function, modifying their values only affects these exact local copies within the function and not the values of the original Variables. To account for this limitation we can, instead, pass a Pointer as an argument to a function, which previously had been assigned the main memory “Address” of a Variable of interest. By employing this trick we are not actually passing the original Variable as an argument to the function but instead, we are passing a Pointer capable of pointing to the main memory “Address” of the original Variable, and because of that capable of allowing for the manipulation of the original Variable’s value.

    alternative

    alternative

    Download "PointersFunctions"

    For us to understand the way this piece of code works need to focus first on lines 7 through 12. The effectively three lines of code realise a function the argument of which is a Pointer (“LocalPointerGlobalAccess”), with its purpose being a twofold directly implied by its name, namely: a) to provide a “Local” Variable for the function, and b) to provide global-like access to the value of Variable “X”.
    The next two most important commands are the command at line 24 and the command at line 29. Both these commands call the function “CallFunctionWithPointer” the first by passing as a parameter the Pointer that “points” on the Variables main memory “Address” and the second, by passing as a parameter the main memory “Address” of Variable “X”. From this description it becomes apparent that both calls are equivalent and achieve exactly the same thing, that is, to initialise the Pointer at the argument of the function with the main memory “Address” of Variable “X”. Taking this a step further we can say that the command lines are directly equivalent to the following:

    int *LocalPointerGlobalAccess;

    LocalPointerGlobalAccess = &X;

    which explains in actual terms why the passing of the Pointer initialised to the Variables main memory “Address” at first, and directly the main memory “Address” of the Variable second, are syntactically valid. The net result of this trick is that the value in Variable “X” keeps increasing by “25”, with every call of the function.


  • POINTERS INITIALISATION
    If by declaring a Pointer we need to postpone its assignment to a main memory “Address” belonging to a Variable for some point later in our code, we can still initialise our Pointer by making use of the “NULL” directive.

    alternative

    Download "InitialisePointer"

    The command at line 12 serves the purpose, by effectively initialising the Pointer “Y” to “point” to nothing.