What are Pointers in C Programming Language
Pointers in the c program are simple and enjoyable to learn.
Some C programming tasks are easier to complete with pointers, while others, such as dynamic memory allocation, are impossible without them.
To become a proficient C programmer, learning pointers is vital. Let’s begin by studying them in little steps.
Every variable, as you may know, is a memory location.
Each memory location has an address that can be accessed using the ampersand (&) operator, which denotes a memory address.
Look at the sample below, which prints the addresses of the variables defined.
With the help of examples, you’ll learn about pointers, including what they are, how to use them, and common mistakes you could make when working with them.
Try to run the C Programming code for free through online
In C programming, pointers are extremely useful.
Let’s start with addresses in C programming before moving on to pointers.
Let’s look at the example below:
#include <stdio.h> int main () { int var1; char var2[10]; printf("Address of var1 variable: %x\n", &var1 ); printf("Address of var2 variable: %x\n", &var2 ); return 0; }
When the example code is compiled and run, the following result is obtained:
Address of var1 variable: bff5a400
Address of var2 variable: bff5a3f6
You can test the above example here! ➡ C Online Compiler
What is Pointers in C Programming?
The pointer is a variable whose value is the address of another variable, i.e. the memory location’s direct address.
A pointer, like any other variable or constant, must be declared before it may be used to store any variable address.
This pointer variable declaration takes the following general form:
type *var-name;
The pointer’s base type is type, which must be a valid C data type, and the pointer variable’s name is var-name.
The asterisk * that is used to declare a pointer is the same as the asterisk that is used to multiply.
The asterisk, on the other hand, is used to indicate a variable as a pointer in this sentence.
Take a look at a few examples of proper pointer declarations.
int *ip; /* pointer to an integer */ double *dp; /* pointer to a double */ float *fp; /* pointer to a float */ char *ch /* pointer to a character */
All pointer values, whether integer, float, character, or other, have the same data type: a lengthy hexadecimal number that denotes a memory address.
The data type of the variable or constant to which the pointer points is the only difference between pointers of different data kinds.
How to Use Pointers?
Integer, float, character, and other pointer values all share the same data type: a long hexadecimal number that specifies a memory address.
The sole distinction between pointers of different data types is the data type of the variable or constant to which the pointer points.
Let’s Look at the example below:
#include <stdio.h> int main () { int var = 20; /* actual variable declaration */ int *ip; /* pointer variable declaration */ ip = &var; /* store address of var in pointer variable*/ printf("Address of var variable: %x\n", &var ); /* address stored in pointer variable */ printf("Address stored in ip variable: %x\n", ip ); /* access the value using the pointer */ printf("Value of *ip variable: %d\n", *ip ); return 0; }
When the preceding code is compiled and run, the following result is obtained:
Address of var variable: bffd8b3c
Address stored in ip variable: bffd8b3c
Value of *ip variable: 20
You can test the above example here! ➡ C Online Compiler
NULL Pointers
If you don’t have an exact location to assign to a pointer variable, it’s always a good idea to assign a NULL value to it.
This is done when the variable is declared. A null pointer is a pointer that has been assigned the value NULL.
The NULL pointer is a zero-valued constant found in numerous standard libraries. Take a look at the following program:
#include <stdio.h> int main () { int *ptr = NULL; printf("The value of ptr is : %x\n", ptr ); return 0; }
When the preceding code is compiled and run, the following is the result:
The value of ptr is 0
Because the operating system reserves memory at address 0, most operating systems do not allow programs to access memory at that address.
The memory address 0 has unique importance; it indicates that the pointer is not intended to point to a memory location that is accessible.
However, a pointer with the null (zero) value is assumed to point to nothing by convention.
You can use a ‘if’ statement to check for a null pointer, as seen below:
if(ptr) /* succeeds if p is not null */ if(!ptr) /* succeeds if p is null */
You can test the above example here! ➡ C Online Compiler
Pointers in Detail
Pointers have a lot of notions, but they’re all simple, and they’re highly fundamental in C programming.
Any C programmer should be familiar with the following key pointer concepts:
Concept | Description |
---|---|
Pointer arithmetic | There are four arithmetic operators that can be used in pointers: ++, –, +, – |
Array of pointers | You can define arrays to hold a number of pointers. |
Pointer to pointer | C allows you to have pointer on a pointer and so on. |
Passing pointers to functions in C | Passing an argument by reference or by address enable the passed argument to be changed in the calling function by the called function. |
Return pointer from functions in C | C allows a function to return a pointer to the local variable, static variable, and dynamically allocated memory as well. |
C Pointers and Arrays
You’ll learn about the relationship between arrays and pointers in C programming in this course.
You’ll also learn how to use pointers to access array elements.
Check out these two topics before learning about the link between arrays and pointers:
- C Arrays
- C Pointers
Relationship Between Arrays and Pointers
An array is a collection of data that is arranged in a logical order. Let’s develop a program to print array element addresses.
#include <stdio.h> int main() { int x[4]; int i; for(i = 0; i < 4; ++i) { printf("&x[%d] = %p\n", i, &x[i]); } printf("Address of array x: %p", x); return 0; }
Output:
&x[0] = 1450734448
&x[1] = 1450734452
&x[2] = 1450734456
&x[3] = 1450734460
Address of array x: 1450734448
Between two successive items of array x, there is a difference of 4 bytes. It’s because int has a size of 4 bytes (on our compiler).
It’s worth noting that the addresses of &x[0] and x are identical. It’s because the variable x refers to the array’s first element.
It is evident from the preceding example that &x[0] is equivalent to x. Also, x[0] is the same as *x.
Similarly,
- &x[1] is the same as x+1, and x[1] is the same as *(x+1).
- &x[2] is the same as x+2 and x[2] is the same as *(x+2).
- …
- Essentially, &x[i] is the same as x+i, and x[i] is the same as *(x+i).
You can test the above example here! ➡ C Online Compiler
Example of Pointers and Arrays
#include <stdio.h> int main() { int i, x[6], sum = 0; printf("Enter 6 numbers: "); for(i = 0; i < 6; ++i) { // Equivalent to scanf("%d", &x[i]); scanf("%d", x+i); // Equivalent to sum += x[i] sum += *(x+i); } printf("Sum = %d", sum); return 0; }
When you run the code, you’ll get the following results:
Enter 6 numbers: 2
3 4 4 12 4
Sum = 29
We’ve declared an array x with six items. We utilized pointers to access the array’s elements.
In the vast majority of cases, array names devolve into pointers. Array names are transformed into pointers in simple terms.
It is for this reason that pointers can be used to access array elements. However, keep in mind that pointers and arrays are not the same thing.
There are a few exceptions to the rule that array names do not devolve into pointers.
For further information, see When does an array name not decay into a pointer?
You can test the above example here! ➡ C Online Compiler
Another Example of Arrays and Pointers
#include <stdio.h> int main() { int x[5] = {1, 2, 3, 4, 5}; int* ptr; // ptr is assigned the address of the third element ptr = &x[2]; printf("*ptr = %d \n", *ptr); // 3 printf("*(ptr+1) = %d \n", *(ptr+1)); // 4 printf("*(ptr-1) = %d", *(ptr-1)); // 2 return 0; }
When you run the code, you’ll get the following results:
*ptr = 3
*(ptr+1) = 4
*(ptr-1) = 2
The third element’s address, &x[2, is allocated to the ptr pointer in this example. As a result, when we printed *ptr, we got 3.
The fourth element is obtained by printing *(ptr+1). Similarly, we may get the second element by writing *(ptr-1).
You can test the above example here! ➡ C Online Compiler
C Pass Addresses and Pointers
With the help of examples, you’ll learn how to give addresses and pointers as parameters to functions in this article.
Addresses can also be passed as arguments to functions in C programming.
We can use pointers in the function definition to accept these addresses. Because pointers are used to hold addresses, this is the case.
Consider the following scenario:
Example of Pass Addresses to Functions
#include <stdio.h> void swap(int *n1, int *n2); int main() { int num1 = 5, num2 = 10; // address of num1 and num2 is passed swap( &num1, &num2); printf("num1 = %d\n", num1); printf("num2 = %d", num2); return 0; } void swap(int* n1, int* n2) { int temp; temp = *n1; *n1 = *n2; *n2 = temp; }
When you run the code, you’ll get the following results:
num1 = 10
num2 = 5
swap(&num1, &num2); is used to pass the addresses of num1 and num2 to the swap() function.
In the function definition, pointers n1 and n2 accept these parameters.
void swap(int* n1, int* n2) {
... ..
}
When *n1 and *n2 are modified in the swap() function, the main() function’s num1 and num2 are likewise changed.
*n1 and *n2 were switched inside the swap() procedure. As a result, num1 and num2 have been swapped.
Swap() does not return anything because its return type is void.
You can test the above example here! ➡ C Online Compiler
C Dynamic Memory Allocation
In this article, you’ll learn how to use standard library functions like malloc(), calloc(), free(), and realloc() to dynamically allocate memory in your C application ().
An array is a collection of a fixed number of values, as you may know. You can’t adjust the size of an array once it’s been declared.
It’s possible that the array you declared isn’t big enough. You can manually allocate RAM during runtime to remedy this problem.
In C programming, this is referred to as dynamic memory allocation.
Malloc(), calloc(), realloc(), and free() are library functions that are used to dynamically allocate memory.
The header file <stdlib.h> defines these functions.
C malloc()
Memory allocation is referred to as “malloc”.
The malloc() method sets aside a memory block of the specified size.
It also returns a void pointer that can be cast into any type of pointer.
The Syntax of malloc()
ptr = (castType*) malloc(size);
Example:
ptr = (float*) malloc(100 * sizeof(float));
The preceding statement sets aside 400 bytes of RAM. The reason for this is because float has a size of 4 bytes.
The pointer ptr holds the address of the allocated memory’s initial byte.
If the memory cannot be allocated, the expression returns a NULL pointer.
C calloc()
Contiguous allocation is represented by the term “calloc”.
The malloc() function allocates memory but does not initialize it, whereas the calloc() function allocates memory but does not initialize it.
The Syntax of calloc()
ptr = (castType*)calloc(n, size);
Example:
ptr = (float*) calloc(25, sizeof(float));
The above statement allocates contiguous memory space for 25 float elements.
C free()
Memory that has been dynamically allocated with calloc() or malloc() does not get released on its own.
To release the space, you must use free() directly.
The Syntax of free()
free(ptr);
The space allocated in the memory pointed by ptr is freed with this statement.
The Example of malloc() and free()
// Program to calculate the sum of n numbers entered by the user #include <stdio.h> #include <stdlib.h> int main() { int n, i, *ptr, sum = 0; printf("Enter number of elements: "); scanf("%d", &n); ptr = (int*) malloc(n * sizeof(int)); // if memory cannot be allocated if(ptr == NULL) { printf("Error! memory not allocated."); exit(0); } printf("Enter elements: "); for(i = 0; i < n; ++i) { scanf("%d", ptr + i); sum += *(ptr + i); } printf("Sum = %d", sum); // deallocating the memory free(ptr); return 0; }
Output:
Enter number of elements: 3
Enter elements: 100
20
36
Sum = 156
We’ve dynamically allocated RAM for n ints in this case.
You can test the above example here! ➡ C Online Compiler
C realloc()
You can use the realloc() function to alter the size of previously allocated memory if the dynamically allocated memory is insufficient or more than required.
Ptr is reallocated with a new size x in this case.
Example of realloc()
#include <stdio.h> #include <stdlib.h> int main() { int *ptr, i , n1, n2; printf("Enter size: "); scanf("%d", &n1); ptr = (int*) malloc(n1 * sizeof(int)); printf("Addresses of previously allocated memory:\n"); for(i = 0; i < n1; ++i) printf("%pc\n",ptr + i); printf("\nEnter the new size: "); scanf("%d", &n2); // rellocating the memory ptr = realloc(ptr, n2 * sizeof(int)); printf("Addresses of newly allocated memory:\n"); for(i = 0; i < n2; ++i) printf("%pc\n", ptr + i); free(ptr); return 0; }
Output:
Enter size: 2
Addresses of previously allocated memory:
26855472
26855476
Enter the new size: 4
Addresses of newly allocated memory:
26855472
26855476
26855480
26855484
You can test the above example here! ➡ C Online Compiler
Summary
To become a proficient C programmer, it is vital to learn pointers.
A pointer is a variable whose value is the address of another variable’s direct address.
Every C variable is a memory location, and each memory location has an address that can be accessed using the ampersand (&) operator.
If you have any questions or suggestions about What are Pointers in C Programming Language, please feel free to leave a comment below.
PREVIOUS
NEXT