Pointer in c
By Paribesh Sapkota
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.
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:
- Pointer Declaration
- Pointer Initialization
- 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;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; Advantages and disadvantages of pointer Advantage:
- Pointers provide direct access to memory
- Pointers provide a way to return more than one value to the functions
- Reduces the storage space and complexity of the program
- Reduces the execution time of the program
- Provides an alternate way to access array elements
Drawbacks of pointers in c:
- Uninitialized pointers might cause segmentation fault.
- Dynamically allocated block needs to be freed explicitly. Otherwise, it would lead to memory leak.
- Pointers are slower than normal variables.
- If pointers are updated with incorrect values, it might lead to memory corruption.
The & and * operators play crucial roles when working with pointers:
- Address-of Operator (&):
- The & operator is also known as the “address-of operator.”
- It is used for referencing, which means taking the address of an existing variable.
- When you use & in front of a variable, it gives you the memory address where that variable is stored.
int i = 42; int* ptr = &i; // ptr now points to the memory location of 'i'
Dereference Operator (*):
- The * operator is also known as the “dereference operator.”
- It is used to access the value stored at a memory address pointed to by a pointer.
- When you use * in front of a pointer, it retrieves the value stored at that memory location.
int j = *ptr; // 'j' now holds the value 42 (retrieved from the memory location pointed to by 'ptr')Pointer to Pointer (Pointer-to-Pointer):
- Sometimes, you need to work with pointers that point to other pointers.
- The & operator can create a pointer to a pointer (a pointer-to-pointer).
int** ipp; // Declare a pointer to a pointer int k = 99; int* ip1 = &k; // 'ip1' points to 'k' ipp = &ip1; // 'ipp' now points to 'ip1'Pointer Arithmetic
The Pointer arithmetic refers to the legal or valid arithmetic operations that can be performed on a pointer. It is slightly different from the ones that we generally use for mathematical calculations as only a limited set of operations can be performed on pointers. These operations include:
- Increment in a Pointer
- Decrement in a Pointer
- Addition of integer to a pointer
- Subtraction of integer to a pointer
- Subtracting two pointers of the same type
- Comparison of pointers of the same type.
- Assignment of pointers of the same type.
Incrementing Pointer in C
If we increment a pointer by 1, the pointer will start pointing to the immediate next location. This is somewhat different from the general arithmetic since the value of the pointer will get increased by the size of the data type to which the pointer is pointing.
The Rule to increment the pointer is given below:
- new_address= current_address + i * size_of(data type)
Where i is the number by which the pointer get increased.
32-bit
For 32-bit int variable, it will be incremented by 2 bytes.
64-bit
For 64-bit int variable, it will be incremented by 4 bytes.
#include<stdio.h> int main(){ int number=50; int *p;//pointer to int p=&number;//stores the address of number variable printf("Address of p variable is %u \n",p); p=p+1; printf("After increment: Address of p variable is %u \n",p); // in our case, p will get incremented by 4 bytes. return 0; }Decrementing Pointer in C
Like increment, we can decrement a pointer variable. If we decrement a pointer, it will start pointing to the previous location. The formula of decrementing the pointer is given below:
- new_address= current_address – i * size_of(data type)
32-bit
For 32-bit int variable, it will be decremented by 2 bytes.
64-bit
For 64-bit int variable, it will be decremented by 4 bytes.
#include <stdio.h> void main(){ int number=50; int *p;//pointer to int p=&number;//stores the address of number variable printf("Address of p variable is %u \n",p); p=p-1; printf("After decrement: Address of p variable is %u \n",p); // P will now point to the immidiate previous location. }Pointer Addition
#include<stdio.h> int main(){ int number=50; int *p;//pointer to int p=&number;//stores the address of number variable printf("Address of p variable is %u \n",p); p=p+3; //adding 3 to pointer variable printf("After adding 3: Address of p variable is %u \n",p); return 0; }Pointer Subtraction
#include<stdio.h> int main(){ int number=50; int *p;//pointer to int p=&number;//stores the address of number variable printf("Address of p variable is %u \n",p); p=p-3; //subtracting 3 from pointer variable printf("After subtracting 3: Address of p variable is %u \n",p); return 0; }Illegal arithmetic with pointers
There are various operations which can not be performed on pointers. Since, pointer stores address hence we must ignore the operations which may lead to an illegal address, for example, addition, and multiplication. A list of such operations is given below.
- Address + Address = illegal
- Address * Address = illegal
- Address % Address = illegal
- Address / Address = illegal
- Address & Address = illegal
- Address ^ Address = illegal
- Address | Address = illegal
- ~Address = illegal
Pointer to function
#include<stdio.h> int addition (); int main () { int result; int (*ptr)(); ptr = &addition; result = (*ptr)(); printf("The sum is %d",result); } int addition() { int a, b; printf("Enter two numbers?"); scanf("%d %d",&a,&b); return a+b; }
Array of functions in C
#include<stdio.h> int show(); int showadd(int); int (*arr[3])(); int (*(*ptr)[3])(); int main () { int result1; arr[0] = show; arr[1] = showadd; ptr = &arr; result1 = (**ptr)(); printf("printing the value returned by show : %d",result1); (*(*ptr+1))(result1); } int show() { int a = 65; return a++; } int showadd(int b) { printf("\nAdding 90 to the value returned by show: %d",b+90); }
Pointers and Character Strings
Strings in C are arrays of characters, and pointers can be used to manipulate them.
char str[] = "Hello"; char *ptr = str; while (*ptr != '\0') { printf("%c", *ptr); ptr++; }
Array of Pointers
An array of pointers can be used to store a list of strings.
char *arr[] = {"Hello", "World", "C Programming"}; for (int i = 0; i < 3; i++) { printf("%s\n", arr[i]); }
Pointers as Function Arguments
Pointers can be passed to functions to modify the original variables.
void increment(int *ptr) { (*ptr)++; } int main() { int num = 10; increment(&num); printf("%d\n", num); // Outputs 11 }
Function Returning Pointers
Functions can return pointers, allowing for dynamic memory allocation within functions.
#include <stdlib.h> int* createArray(int size) { int *arr = (int *)malloc(size * sizeof(int)); for (int i = 0; i < size; i++) { arr[i] = i + 1; } return arr; } int main() { int *arr = createArray(5); for (int i = 0; i < 5; i++) { printf("%d ", arr[i]); } free(arr); }
Pointers and Structures
Pointers to structures allow for efficient manipulation and dynamic allocation of complex data types.
struct Point { int x, y; }; void printPoint(struct Point *p) { printf("Point(%d, %d)\n", p->x, p->y); } int main() { struct Point p1 = {10, 20}; printPoint(&p1); }
Dynamic Memory Allocation
Dynamic memory allocation is a powerful feature in C that allows you to allocate memory during program execution. This enables you to create data structures of varying sizes and lifetimes, such as arrays, linked lists, trees, and more. Dynamic memory allocation is typically done using the malloc
, calloc
, realloc
, and free
functions from the <stdlib.h>
library.
malloc
Function
The malloc
function allocates a block of memory of a specified size and returns a pointer to the beginning of the block
#include <stdio.h> #include <stdlib.h> int main() { int *ptr; // Allocate memory for 5 integers ptr = (int *)malloc(5 * sizeof(int)); if (ptr == NULL) { printf("Memory allocation failed\n"); return 1; } // Use the allocated memory for (int i = 0; i < 5; i++) { ptr[i] = i + 1; printf("%d ", ptr[i]); } // Free the allocated memory free(ptr); return 0; }
calloc
Function
The calloc
function is used to allocate memory for an array of elements, initialized to zero.
#include <stdio.h> #include <stdlib.h> int main() { int *ptr; // Allocate memory for 5 integers initialized to zero ptr = (int *)calloc(5, sizeof(int)); if (ptr == NULL) { printf("Memory allocation failed\n"); return 1; } // Use the allocated memory for (int i = 0; i < 5; i++) { printf("%d ", ptr[i]); // Will print all zeros } // Free the allocated memory free(ptr); return 0; }
realloc
Function
The realloc
function changes the size of the previously allocated memory block. It may move the block to a new location in memory.
#include <stdio.h> #include <stdlib.h> int main() { int *ptr; // Allocate memory for 5 integers ptr = (int *)malloc(5 * sizeof(int)); if (ptr == NULL) { printf("Memory allocation failed\n"); return 1; } // Use the allocated memory for (int i = 0; i < 5; i++) { ptr[i] = i + 1; printf("%d ", ptr[i]); } // Reallocate memory for 10 integers ptr = (int *)realloc(ptr, 10 * sizeof(int)); if (ptr == NULL) { printf("Memory reallocation failed\n"); return 1; } // Use the reallocated memory for (int i = 5; i < 10; i++) { ptr[i] = i + 1; printf("%d ", ptr[i]); } // Free the allocated memory free(ptr); return 0; }
free
Function
The free
function deallocates the memory previously allocated by malloc
, calloc
, or realloc
.