Unit 1 C Pointer Notes APC
Unit 1 C Pointer Notes APC
Rakesh Pandit
C Pointers: -
•
Pointers are one of the core components of the C programming language.
A pointer can be used to store the memory address of other variables,
functions, or even other pointers. The use of pointers allows low-level
memory access, dynamic memory allocation, and many other functionality in C.
In this article, we will discuss C pointers in detail, their types, uses, advantages,
and disadvantages with examples.
What is a Pointer in C?
A pointer is defined as a derived data type that can store the address of other
C variables or a memory location. We can access and manipulate the data
stored in that memory location using pointers.
As the pointers in C store the memory addresses, their size is independent of the
type of data they are pointing to. This size of pointers in C only depends on the
system architecture.
Syntax of C Pointers
The syntax of pointers is similar to the variable declaration in C, but we use the (
* ) dereferencing operator in the pointer declaration.
datatype * ptr;
where
• ptr is the name of the pointer.
• datatype is the type of data it is pointing to.
The above syntax is used to define a pointer to a variable. We can also define
pointers to functions, structures, etc.
How to Use Pointers?
The use of pointers in C can be divided into three steps:
1. Pointer Declaration
2. Pointer Initialization
3. Pointer Dereferencing
1. Pointer Declaration
In pointer declaration, we only declare the pointer but do not initialize it. To
declare a pointer, we use the ( * ) dereference operator before its name.
Example
int *ptr;
The pointer declared here will point to some random memory address as it is not
initialized. Such pointers are called wild pointers.
2. Pointer Initialization
Pointer initialization is the process where we assign some initial value to the
pointer variable. We generally use the ( & ) addressof operator to get the
memory address of a variable and then store it in the pointer variable.
Example
int var = 10;
int * ptr;
ptr = &var;
APC Notes
Rakesh Pandit
We can also declare and initialize the pointer in a single step. This method is
called pointer definition as the pointer is declared and initialized at the same
time.
Example
int *ptr = &var;
Note: It is recommended that the pointers should always be initialized to some
value before starting using it. Otherwise, it may lead to number of errors.
3. Pointer Dereferencing
Dereferencing a pointer is the process of accessing the value stored in the
memory address specified in the pointer. We use the same ( * ) dereferencing
operator that we used in the pointer declaration.
Dereferencing a Pointer in C
C Pointer Example
• C
void geeks()
{
int var = 10;
// Driver program
int main()
{
geeks();
return 0;
}
Output
Value at ptr = 0x7fff1038675c
Value at var = 10
Value at *ptr = 10
Types of Pointers in C
Pointers in C can be classified into many different types based on the parameter
on which we are defining their types. If we consider the type of variable stored in
the memory location pointed by the pointer, then the pointers can be classified
into the following types:
1. Integer Pointers
As the name suggests, these are the pointers that point to the integer values.
Syntax
int *ptr;
These pointers are pronounced as Pointer to Integer.
Similarly, a pointer can point to any primitive data type. It can point also point to
derived data types such as arrays and user-defined data types such as structures.
2. Array Pointer
Pointers and Array are closely related to each other. Even the array name is the
pointer to its first element. They are also known as Pointer to Arrays. We can
create a pointer to an array using the given syntax.
Syntax
char *ptr = &array_name;
Pointer to Arrays exhibits some interesting properties which we discussed later
in this article.
3. Structure Pointer
The pointer pointing to the structure type is called Structure Pointer or Pointer
to Structure. It can be declared in the same way as we declare the other primitive
data types.
Syntax
struct struct_name *ptr;
In C, structure pointers are used in data structures such as linked lists, trees, etc.
4. Function Pointers
Function pointers point to the functions. They are different from the rest of the
pointers in the sense that instead of pointing to the data, they point to the code.
Let’s consider a function prototype – int func (int, char), the function pointer for
this function will be
Syntax
int (*ptr)(int, char);
APC Notes
Rakesh Pandit
Note: The syntax of the function pointers changes according to the function
prototype.
5. Double Pointers
In C language, we can define a pointer that stores the memory address of another
pointer. Such pointers are called double-pointers or pointers-to-pointer. Instead
of pointing to a data value, they point to another pointer.
Syntax
datatype ** pointer_name;
Dereferencing Double Pointer
*pointer_name; // get the address stored in the inner level pointer
**pointer_name; // get the value pointed by inner level pointer
Note: In C, we can create multi-level pointers with any number of levels such as –
***ptr3, ****ptr4, ******ptr5 and so on.
6. NULL Pointer
The Null Pointers are those pointers that do not point to any memory location.
They can be created by assigning a NULL value to the pointer. A pointer of any
type can be assigned the NULL value.
Syntax
data_type *pointer_name = NULL;
or
pointer_name = NULL
It is said to be good practice to assign NULL to the pointers currently not in use.
7. Void Pointer
The Void pointers in C are the pointers of type void. It means that they do not
have any associated data type. They are also called generic pointers as they can
point to any type and can be typecasted to any type.
Syntax
void * pointer_name;
One of the main properties of void pointers is that they cannot be dereferenced.
Example
int *ptr;
char *str;
9. Constant Pointers
In constant pointers, the memory address stored inside the pointer is constant
and cannot be modified once it is defined. It will always point to the same
memory address.
Syntax
data_type * const pointer_name;
10. Pointer to Constant
The pointers pointing to a constant value that cannot be modified are called
pointers to a constant. Here we can only access the data pointed by the pointer,
but cannot modify it. Although, we can change the address stored in the pointer
to constant.
Syntax
const data_type * pointer_name;
Other Types of Pointers in C:
APC Notes
Rakesh Pandit
There are also the following types of pointers available to use in C apart from
those specified above:
• Far pointer: A far pointer is typically 32-bit that can access memory
outside the current segment.
• Dangling pointer: A pointer pointing to a memory location that has
been deleted (or freed) is called a dangling pointer.
• Huge pointer: A huge pointer is 32-bit long containing segment
address and offset address.
• Complex pointer: Pointers with multiple levels of indirection.
• Near pointer: Near pointer is used to store 16-bit addresses means
within the current segment on a 16-bit machine.
• Normalized pointer: It is a 32-bit pointer, which has as much of its
value in the segment register as possible.
• File Pointer: The pointer to a FILE data type is called a stream pointer
or a file pointer.
Size of Pointers in C
The size of the pointers in C is equal for every pointer type. The size of the
pointer does not depend on the type it is pointing to. It only depends on the
operating system and CPU architecture. The size of pointers in C is
• 8 bytes for a 64-bit System
• 4 bytes for a 32-bit System
The reason for the same size is that the pointers store the memory addresses, no
matter what type they are. As the space required to store the addresses of the
different memory locations is the same, the memory required by one pointer
type will be equal to the memory required by other pointer types.
How to find the size of pointers in C?
We can find the size of pointers using the sizeof operator as shown in the
following program:
Example: C Program to find the size of different pointer types.
// C Program to find the size of different pointers types
#include <stdio.h>
// dummy structure
struct str {
};
// dummy function
void func(int a, int b){};
int main()
{
// dummy variables definitions
int a = 10;
char c = 'G';
struct str x;
APC Notes
Rakesh Pandit
// printing sizes
printf("Size of Integer Pointer \t:\t%d bytes\n",
sizeof(ptr_int));
printf("Size of Character Pointer\t:\t%d bytes\n",
sizeof(ptr_char));
printf("Size of Structure Pointer\t:\t%d bytes\n",
sizeof(ptr_str));
printf("Size of Function Pointer\t:\t%d bytes\n",
sizeof(ptr_func));
printf("Size of NULL Void Pointer\t:\t%d bytes",
sizeof(ptr_vn));
return 0;
}
Output
Size of Integer Pointer : 8 bytes
Size of Character Pointer : 8 bytes
Size of Structure Pointer : 8 bytes
Size of Function Pointer : 8 bytes
Size of NULL Void Pointer : 8 bytes
As we can see, no matter what the type of pointer it is, the size of each and every
pointer is the same.
Now, one may wonder that if the size of all the pointers is the same, then why do
we need to declare the pointer type in the declaration? The type declaration is
needed in the pointer for dereferencing and pointer arithmetic purposes.
#include <stdio.h>
int main()
{
// Declare an array
int v[3] = { 10, 100, 200 };
Output
Value of *ptr = 10
Value of ptr = 0x7ffe8ba7ec50
void geeks()
{
// Declare an array
int val[3] = { 5, 10, 15 };
return;
}
// Driver program
int main()
{
geeks();
return 0;
APC Notes
Rakesh Pandit
Output
Elements of the array are: 5 10 15
Not only that, as the array elements are stored continuously, we can pointer
arithmetic operations such as increment, decrement, addition, and subtraction of
integers on pointer to move between array elements.
Example 2: Accessing Array Elements using Pointer Arithmetic
int main()
{
// defining array
int arr[5] = { 1, 2, 3, 4, 5 };
Output
1 2 3 4 5
This concept is not limited to the one-dimensional array, we can refer to a
multidimensional array element as well using pointers.
APC Notes
Rakesh Pandit
Uses of Pointers in C
The C pointer is a very powerful tool that is widely used in C programming to
perform various useful operations. It is used to achieve the following
functionalities in C:
1. Pass Arguments by Reference
2. Accessing Array Elements
3. Return Multiple Values from Function
4. Dynamic Memory Allocation
5. Implementing Data Structures
6. In System-Level Programming where memory addresses are useful.
7. In locating the exact value at some memory location.
8. To avoid compiler confusion for the same variable name.
9. To use in Control Tables.
Advantages of Pointers
Following are the major advantages of pointers in C:
• Pointers are used for dynamic memory allocation and deallocation.
• An Array or a structure can be accessed efficiently with pointers
• Pointers are useful for accessing memory locations.
• Pointers are used to form complex data structures such as linked lists,
graphs, trees, etc.
• Pointers reduce the length of the program and its execution time as
well.
Disadvantages of Pointers
Pointers are vulnerable to errors and have following disadvantages:
• Memory corruption can occur if an incorrect value is provided to
pointers.
• Pointers are a little bit complex to understand.
• Pointers are majorly responsible for memory leaks in C.
• Pointers are comparatively slower than variables in C.
• Uninitialized pointers might cause a segmentation fault.
int main()
{
int var = 789;
return 0;
}
APC Notes
Rakesh Pandit
Output
Value of var = 789
Value of var using single pointer = 789
Value of var using double pointer = 789
The working of the double-pointer can be explained using the above image:
• The double pointer is declared using the syntax shown above.
• After that, we store the address of another pointer as the value of this
new double pointer.
• Now, if we want to manipulate or dereference to any of its levels, we
have to use Asterisk ( * ) operator the number of times down the level
we want to go.
Size of Pointer to Pointer in C
In the C programming language, a double pointer behaves similarly to a normal
pointer in C. So, the size of the double-pointer variable is always equal to the
normal pointers. We can verify this using the below C Program.
Example 1: C Program to find the size of a pointer to a pointer.
// C program to find the size of pointer to pointer
#include <stdio.h>
int main()
{
// defining single and double pointers
int a = 5;
int* ptr = &a;
int** d_ptr = &ptr;
return 0;
}
Output
Size of normal Pointer: 8
Size of Double Pointer: 8
Note: The output of the above code also depends on the type of machine which is
being used. The size of a pointer is not fixed in the C programming language and
it depends on other factors like CPU architecture and OS used. Usually, for a 64-
APC Notes
Rakesh Pandit
bit Operating System, the size will be 8 bytes and for a 32-bit Operating system,
the size will be 4 bytes.
Application of Double Pointers in C
Following are the main uses of pointer to pointers in C:
• They are used in the dynamic memory allocation of multidimensional
arrays.
• They can be used to store multilevel data such as the text document
paragraph, sentences, and word semantics.
• They are used in data structures to directly manipulate the address of
the nodes without copying.
• They can be used as function arguments to manipulate the address
stored in the local pointer.
Multilevel Pointers in C
Double Pointers are not the only multilevel pointers supported by the C language.
What if we want to change the value of a double pointer?
In this case, we can use a triple pointer, which will be a pointer to a pointer to a
pointer i.e, int ***t_ptr.
Syntax of Triple Pointer
pointer_type *** pointer_name;
Function Pointer in C
Result=5
Here, in the above example, we declare a ‘functionPtr’ that takes two parameters and
returns one. We then assign the address of the function ‘add’ to the pointer and then
call the add function by using the pointer directly.
• We can use function pointers in switch case. Check the examples above
where we use a switch case based on the value of operation.
Function Pointer in C using Arrays
We can have an array of function pointers in C. Let us check an example of function
pointers using an array. The syntax for the function pointer array is
#include <stdio.h>
int add(int a, int b) {
return a + b;
}
int subtract(int a, int b) {
return a – b;
}
int multiply(int a, int b) {
return a * b;
}
int main() {
// Declare an array of function pointers
int (*functionPtrArray[3])(int, int) = {add, subtract, multiply};
// Call functions using function pointers
int result1 = functionPtrArray[0](3, 5);
int result2 = functionPtrArray[1](8, 2);
int result3 = functionPtrArray[2](4, 6);
printf(“Result 1: %d\n”, result1);
printf(“Result 2: %d\n”, result2);
printf(“Result 3: %d\n”, result3);
return 0;
}
Also read: Keywords and Identifiers in C
Output:
Result1: 8
Result2: 6
Result3: 24
We can pass pointers as function arguments in C and can return the pointers from
the function. We can pass a reference to the value stored instead of passing the value
stored inside the variable. This is called pass by reference.
#include <stdio.h>
int add(int a, int b) {
return a + b;
}
int subtract(int a, int b) {
return a – b;
}
int main() {
int (*functionPtr)(int, int);
int a = 10, b = 5;
char operation = ‘+’;
if (operation == ‘+’) {
functionPtr = add;
}
Output:
Result: 15
}
int (*functionPtr)(int, int);
functionPtr = add;
But when we want to dereference a function pointer then we only need to call the
function pointer, just like we call a function. You need to provide the necessary
arguments to the function pointer to deference it.
#include <stdio.h>
// Function prototypes for operations
int add(int a, int b);
int subtract(int a, int b);
int multiply(int a, int b);
int divide(int a, int b);
int main() {
int (*operation)(int, int);
int a, b, result;
char operator;
printf(“Enter operation (+, -, *, /): “);
scanf(” %c”, &operator);
switch (operator) {
case ‘+’:
operation = add;
break;
case ‘-‘:
operation = subtract;
break;
case ‘*’:
operation = multiply;
break;
case ‘/’:
operation = divide;
Break;
default:
printf(“Invalid operation\n”);
return 1;
}
APC Notes
Rakesh Pandit
• Function pointers are used to store the address of the function and
point them whenever needed. Hence, they make the callback
mechanism easy. You can easily pass a function as an argument in C.
• They make the program simple and short.
• Function pointers are used in a program to enhance the flexibility of a
program.
• Function pointers make our code safe.
• We can select functions dynamically at runtime based on various
conditions.
APC Notes
Rakesh Pandit
For example −
p = &qty;
n = *p; n =qty
Example
Given below is the program to demonstrate the functioning of the pointer
operations in C language −
#include<stdio.h>
main ( ){
int x,y;
//Declaring a pointer
int *p;
clrscr ( );
x= 10;
//Assigning value to a pointer
p = &x;
y= *p;
printf ("Value of x = %d", x);
printf ("x is stored at address %u", &x);
printf ("Value of x using pointer = %d", *p);
printf ("address of x using pointer = %u", p);
printf (“value of x in y = %d", y);
*p = 25;
printf ("now x = %d", x)
getch ( );
}
Output
When you execute the above mentioned program, you get the following output
−
Value of x = 10
x is stored at address = 5000
Address of x using pointer = 10
APC Notes
Rakesh Pandit
// Pointer to an integer
int *ptr1, *ptr2;
return 0;
}
Output:
#include <stdio.h>
int main()
{
// Integer variable
int a = 10;
APC Notes
Rakesh Pandit
// Pointer to an integer
int *ptr1, *ptr2;
#include<stdio.h>
int main ()
{
int a = 30, b = 10, *p1, *p2, sum;
p1 = &a;
p2 = &b;
sum = *p1 + *p2;
printf ("Addition of two numbers = %d\n", sum);
sum = *p1 - *p2;
printf ("Subtraction of two numbers = %d\n", sum);
return 0;
}
APC Notes
Rakesh Pandit
Output:
#include <stdio.h>
int main() {
int arr[] = {10, 20, 30, 40, 50};
int *p = arr; // Pointer to the first element of the array
return 0;
}
In this example, p initially points to the first element of arr. After the increment (p++), p
points to the second element.
APC Notes
Rakesh Pandit
Advertisements
int main() {
int arr[] = {10, 20, 30, 40, 50};
int *p = &arr[3]; // Pointer to the fourth element of the
array
return 0;
}
Here, p is set to point to the fourth element of arr. After decrementing (p–), it points to the
third element.
Example 3: Pointer Addition
#include <stdio.h>
int main() {
int arr[] = {10, 20, 30, 40, 50};
int *p = arr; // Pointer to the first element
return 0;
}
In this case, p + 2 moves the pointer p two elements forward, so it points to the third
element (30).
Example 4: Pointer Subtraction
#include <stdio.h>
int main() {
int arr[] = {10, 20, 30, 40, 50};
int *p = &arr[4]; // Pointer to the last element
return 0;
}
p – 2 moves the pointer p two elements back, pointing it to the third element from the last.
int main() {
int arr[] = {10, 20, 30, 40, 50};
int *p1 = &arr[4]; // Pointer to the last element
int *p2 = arr; // Pointer to the first element
return 0;
}
This example calculates the difference between two pointers, p1 and p2, which is the
number of elements between them in the array.