Table of Contents
What are pointers really? How do they work? And most importantly how are they useful?!
In C programming, pointers point to locations. Locations in memory. Life becomes so so easy when you only need to tell the address and not pass the actual variables or structures, etc.
When you pass variables or structures to functions, local temporary copies of those parameters are created in the RAM. This is usually not an issue in computers but in embedded systems every byte of RAM is important. Of course, if the system is much more resource abundant than required, this is not required.
Pointers can save you a lot of hassle with memory. Think about it. You are directly accessing the RAM locations. Use a pointer variable and point it to the location of another variable. You now need just this address to make changes to the variable values.
Now think about a structure that is 50 bytes long. If you pass the whole structure, you are using additional 50 bytes of RAM. You can do away with this by just using the address where the structure begins.
To understand pointers you need to first know a bit about computer memory. Imagine it to be like a bank with a huge number of lockers. Each locker is a memory location and has an address just like a locker has a locker number.
When you declare variables in C or C++, you are giving a locker a name too. So now you call your locker by its name. Suppose
int num=20;
So your locker is named ‘num’ and it has a location in the memory with a locker number or ‘address’ say 5 and you store 20 rupees in it.

Now we’re clear about that, let’s see the technical definition of pointers.
Pointer Definition:
In the simplest of words – A pointer points to a memory location.
A pointer is a variable that contains the memory location of another variable or an array element. We’ll get to arrays later. For now, think of pointers as a tool which provides you access to a variable such as num, by using the address of that variable. A pointer variable is therefore a variable that stores the address of another variable. Read that again!
Note that the datatype of the pointer variables and the variable it points to must be the same.
Application of Pointers in brief
So.. what’s the point of all this? (forgive the pun)
Well pointers are a trick you can use to modify the data declared in one function using code written in another function. What happens normally is, when you pass arguments to a function in a function call, they are treated as local variables in the function and those local variables get a copy of the values passed when you call the function. So you normally, you cannot modify the actual value of those variables in the original function. You’ll just be making a copy and playing with that.
With pointers, you can change the value of the original variable in that other function.
Okay so now that you know it’s a useful trick, continue reading because mastery lies in the details;)
Let’s get back to the locker example. In the locker example, 5 is the address of num. So, you can just pass the address of num to any function and make that function store new values in this address. This approach gives us the power to return more than one value from a function.
General syntax
Pointers are declared just like any other variable. First the datatype, then the name of the pointer variable BUT prefixed by a star “*” (or asterisk..)
data_type *pointer_name;
Example:
int *ptr_num
float *ptr_fnum
So you just declared a pointer variable to point to a variable of specified datatype. Now your pointer ptr_num can store the address of variable num by using the address operator “&”.
int num=20; int *ptr_num: ptr_num = #
Again, if we take the locker example, ptr_num will be equal to 5.
The ‘*’ informs the compiler that you just decalred a pointer variable and ‘int’ specifies that it will store the address of an integer variable.
Similarly a character pointer variable points to a character variable. The ‘&’ operator gets the address of num variable and assigns it to ptr_num pointer variable.
Note: Pointer variables that are not initialized contain garbage value and must not be used before its assigned any variable’s address.
Referencing and Dereferencing
Referencing means taking the address of an existing variable using & and assigning it to a pointer variable.
Dereferencing a pointer means using the * operator to get the value from the memory address that is pointed to by the pointer.
For example:
#include<stdio.h> int main() { int num, *ptrnum; ptrnum = # //Referencing printf("Enter the number:\n"); scanf("%d", &num); printf("The number entered is: %d\n",*ptrnum); //Dereferencing printf("The address of the number in memory is %d:\n",ptrnum); }
Note:The ‘*’ and the ‘&’ operators are inverses of each other. So the value of *(&num) will be num.
Here is another short program to help make it clearer:
Code:
#include<stdio.h> #include<stdlib.h> void main { int num = 20; int *num_ptr; num_ptr = # //Referencing //printing the value of num printf("The value of num is = %d \n",num); //printing the address of num printf("The address of num is = %d \n",&num); //printing the value stored in num_ptr printf("The address of num is = %d \n",num_ptr); //printing the value stored in the address pointed by num_ptr printf("The value of num is = %d \n",*num_ptr); //dereference return 0; }
Output:
The value of num is = 20
The address of num is = 5
(we get this value 5 from our locker example)
The address of num is = 5
(we get this value 5 from our locker example)
The value of num is = 20
- value of num
- address of num
- value stored in num_ptr
- value stored in the address pointed by num_ptr
Referencing
&
is the reference operator. It will refer the memory address to the pointer variable.
int *p; int a=5; p=&a; // Here Pointer variable p refers to the address of integer variable a.
p = &a
or
numPtr = &num
Dereferencing
Dereference operator *
is used by the pointer variable to directly access the value of the variable instead of its memory address.
int *p; int a=5; p=&a; int value=*p; // Value variable will get the value of variable a that pointer variable p pointing to.
Pointer arithmetic
Like other variables in C,
- Pointers can be used in relational expressions like p1>p2
- Shorthand operators ;like += and -= can be used with pointers.
Note: Unary increment and decrement operators have greater [precedence than dereference operator(*). So *ptr++ is the same as *(ptr++) as ++ has greater precedence. The expression will increase the value of ptr so that it points to the next memory location. To increment the value of the variable stored inn ptr, you must write (*ptr)++
So the rules for pointers at a glance are:
- A pointer variable can be assigned the address of another variable of the same type.
- Prefix or postfix increment and decrement operators can be used on pointer variables.
- A C poinitr variable can be compared with another pointer variable of the same type using relational operators.
- A pointer variable cannot be multiplied by a constant or added or subtracted from another pointer variable.
Now let’s look at some special types of pointers.
Special pointers
1. Null pointers
A null pointer does not point to any value. Don’t get me wrong . It’s not garbage. To declare a null pointer a predefined constant NULL is used. NULL is a preprocessor macro which has the value 0.
int *ptr = NULL;
or
int ptr;
ptr=0;
Now remember that your compiler will throw up an error if you try to dereference a NULL pointer because obviously there it does not refer to any valid memory address.
Use of NULL pointer:
Well a function can return a NULL pointer when it cannot perform its task. Also when a pointer in your program points to different places at different times, you can simply initialize it to a NULL pointer because you cannot declare it and simply leave it uninitialized.
2. Generic pointers
The datatype of a generic pointer is void. It is used to point to variables of any datatype. It’s used when you want a pointer to point to different datatypes at different times.
void *ptr;
This too cannot be dereferenced . And you need to typecast a void pointer before using it.
For example:
#inclde<stdio.h> int main() { int x = 10; char ch = 'a'; void *gen_ptr; gen_ptr = &x; //typecasting the pointer to dereference to an integer type printf("Generic pointer points to th eintegher value = %d", *(int*)gen_ptr); //That was typecasting syntax gen_ptr=&ch; printf("\n Generic pointer now points to the character = %c", *(char*)gen_ptr); //Again typecasted, but now to a character datatype return 0; }
OUTPUT:
Generic pointer points to the integer value = 10
Generic pointer now points to the character = a
Now, what are the uses of pointers?
– In embedded programming we get a direct access to device memory. Very often we have to write certain parameters to predefined memory addresses on the chip. Having a language that allows us to easily do so is very handy, of course.
– Because we have direct control on how we handle the used memory. This allows applications to improve their performance greatly which makes C or even C++ a suited programming language for the implementation of high performance solutions such as:
– Mathematical Solvers
– Physic Engines
– Real time simulators
– Rendering in real time
– Working with hardware having limited resources
So that was it about some basics of pointers. Now go ahead and use them in your programs.
Pointers also give you the ability to point to functions. You can then create call back functions.
Pointers are awesome and one of the coolest features of C and C++. Pointers is one of the reasons why C is still the language of choice in embedded systems. Pointer are power, but remember, “With great power comes greater responsibility.”
Also check out this video on pointers on our Youtube channel
For examples of programs on pointers check out this post: