Programming: References and Pointers

In C, all function parameters are pass-by-value by default. In other words, when a variable is used as an input parameter to a function, a copy of that variable is created within the scope of the function. Thus, the original variable is entirely unaffected when the function executes. Instead, any changes to the variable made within the function are done to the copy rather than the original. The pass-by-value method is useful if you want the variable’s value and do not need to change the variable itself. 

If you want the function to manipulate the variable, however, it will need to be passed by reference. In contrast with pass-by-value, a parameter that is pass-by-reference will pass a pointer to the original variable. Thus the original variable can be modified during the function’s execution.  

Let us recall a pointer is a variable that holds the memory address of another variable. They are imperative for implementing pass-by-reference parameters. By giving the address of the desired variable to the function, the function can trace the memory address back to the original variable, allowing it to modify the variable directly. 

In order to implement and use pointers effectively, it is important to know how to use the reference and dereference operators. The reference operator (&) returns the memory address of a variable. You can create or reassign pointers (which are essentially just memory addresses) from variables by placing the reference operator before the variable name. In the below example, myVariable is an integer while myPtr is a pointer to the integer. We use the  & operator to assign the address of myVariable to myPtr.

int myVariable;

int *myPtr;

myPtr = &myVariable;

The reference operator can also be used to pass a variable by reference. Since the parameter only needs a memory address to work with, you can use the reference operator to pass the address without creating a new pointer. If we had a function that had a single pass-by-reference parameter called myFunc, then the following syntax would be valid:

// The declaration of the myFunc

void myFunc(int *myParameter);


// The usage of myFunc can be as follows:

myFunc(&myVariable);

myFunc will use the address pointing to myVariable within the function. Note that passing myVariable without the ampersand will not throw errors, meaning it is syntactically valid. However, it may give you unintended behavior. Rather than passing the address of myVariable, the function call would instead pass the address of a variable whose address matches the value stored in myVariable. In other words, if myVariable had a value of 2 and an address space of 0x0481, the function would use the variable whose address space is 0x0002. Make sure you remember the ampersand if you are trying to pass the address of a variable instead of the variable itself!


The dereference operator (*) returns the variable that a memory address is pointing to. The dereference operator allows you to use a pointer to directly change the variable that it is pointing to. Suppose you had a pointer myPtr pointing to a variable myVariable. Using the dereference operator on myPtr gives you access to myVariable.

int myVariable;

int *myPtr;

myPtr = &myVariable;

myVariable = 1;

*myPtr = 2;

After these lines are executed, the value of myVariable will be 2, not 1. myPtr will retain its value, as it is still pointing to myVariable. The dereference operator can also be used to pass variables into functions with pass-by-value parameters. If we had a function with a single pass-by-value parameter called myOtherFunc, then the following syntax would be valid:

// The declaration of myOtherFunc

void myOtherFunc(int myOtherParameter);


// The usage of myOtherFunc can be as follows:

myOtherFunc(*myPtr);

myOtherFunc will use the value contained in the variable that myPtr points to, which would be myVariable. Without the asterisk, myOtherFunc would instead create a copy of the memory address’s value itself, rather than the value of the variable pointed to. Keep in mind that a memory address is just a number, and that is precisely how myOtherFunc will treat it if the asterisk is left off from a pointer.


These operators can be used in declarations. To declare a pointer to a variable, you must use the dereference operator in the declaration such as the below line. 

int *myPtr;

Just keep in mind that myPtr will be pointing to a random memory location. Before you start using the dereference operator on myPtr, be sure to assign it to a memory address.

int *myPtr;

myPtr = &myVariable;


programming example

https://github.com/VT-Introduction-to-Embedded-systems/programmimng_pointers_struct.git