Author: saqibkhan

  • Passing Pointers to Functions

    A pointer In C is a variable that stores the address of another variable. It acts as a reference to the original variable. A pointer can be passed to a function, just like any other argument is passed.

    A function in C can be called in two ways −

    • Call by Value
    • Call by Reference

    To call a function by reference, you need to define it to receive the pointer to a variable in the calling function. Here is the syntax that you would use to call a function by reference −

    type function_name(type *var1, type *var2,...)

    When a function is called by reference, the pointers of the actual argument variables are passed, instead of their values.

    Advantages of Passing Pointers to Functions

    Passing a pointer to a function has two advantages −

    • It overcomes the limitation of pass by value. Changes to the value inside the called function are done directly at the address stored in the pointer. Hence, we can manipulate the variables in one scope from another.
    • It also overcomes the limitation of a function that it can return only one expression. By passing pointers, the effect of processing of a function takes place directly at the address. Secondly, more than one values can be returned if we return a pointer of an array or struct variable.

    In this chapter, we shall see how to −

    • Pass pointers to int variables
    • Pass pointers to array
    • Pass pointer to structure

    Example of Passing Pointers to Functions

    Let us define a function add() that receives the references of two variables. When such a function is called, we pass the address of the actual argument. Let us call the add() function by reference from inside the main() function.

    #include <stdio.h>/* function declaration */intadd(int*,int*);intmain(){int a =10, b =20;int c =add(&a,&b);printf("Addition: %d", c);}intadd(int*x,int*y){int z =*x +*y;return z;}

    Output

    Addition: 30
    

    Swap Values by Passing Pointers

    One of the most cited applications of passing a pointer to a function is how we can swap the values of two variables.

    The following function receives the reference of two variables whose values are to be swapped −

    /* function definition to swap the values */intswap(int*x,int*y){int z;
       z =*x;/* save the value at address x */*x =*y;/* put y into x */*y = z;/* put z into y */return0;}

    Example

    The main() function has two variables a and b; their addresses are passed as arguments to the swap() function.

    #include <stdio.h>intswap(int*x,int*y){int z;
       z =*x;*x =*y;*y = z;}intmain(){/* local variable definition */int a =10;int b =20;printf("Before swap, value of a: %d\n", a);printf("Before swap, value of b: %d\n", b);/* calling a function to swap the values */swap(&a,&b);printf("After swap, value of a: %d\n", a);printf("After swap, value of b: %d\n", b);return0;}

    Output

    When you execute this code, it will produce the following output −

    Before swap, value of a: 10
    Before swap, value of b: 20
    After swap, value of a: 20
    After swap, value of b: 10
    

    Passing an Array Pointer to a Function

    In C programming, the name of an array acts the address of the first element of the array; in other words, it becomes a pointer to the array.

    Example

    In this example, we declare an uninitialized array in main() and pass its pointer to a function along with an integer.

    Inside the function, the array is filled with the square, cube and square root of the passed integer. The function returns the pointer of this array, using which the values are accessed and printed in the main() function.

    #include <stdio.h>#include <math.h>intarrfunction(int,float*);intmain(){int x =100;float arr[3];arrfunction(x, arr);printf("Square of %d: %f\n", x, arr[0]);printf("Cube of %d: %f\n", x, arr[1]);printf("Square root of %d: %f\n", x, arr[2]);return0;}intarrfunction(int x,float*arr){
       arr[0]=pow(x,2);
       arr[1]=pow(x,3);
       arr[2]=pow(x,0.5);}

    Output

    When you run this code, it will produce the following output −

    Square of 100: 10000.000000
    cube of 100: 1000000.000000
    Square root of 100: 10.000000
    

    Passing String Pointers to a Function

    Let us have a look at another example, where we will pass string pointers to a function.

    Example

    In this program, two strings are passed to the compare() function. A string in C is an array of char data type. We use the strlen() function to find the length of the string.

    #include <stdio.h>intcompare(char*,char*);intmain(){char str1[]="BAT";char str2[]="BALL";int ret =compare(str1, str2);return0;}intcompare(char*x,char*y){int val;if(strlen(x)>strlen(y)){printf("Length of Str1 is greater than or equal to the length of Str2");}else{printf("Length of Str1 is less than the length of Str2");}}

    Output

    When you run this code, it will produce the following output −

    Length of Str1 is less than the length of Str2
    

    Passing Struct Pointer to a Function

    In C programming, a structure is a heterogenous data type containing elements of different data types. Let’s see how we can pass a struct pointer to a function.

    Example

    In this example, a struct variable rectangle is declared in main() and its address is passed to a user-defined function called area(). When called, the area() function is able to use the elements of the variable with the indirection operator “”. It computes the result and assigns it to the area element rarea.

    #include <stdio.h>#include <string.h>structrectangle{float len, brd;double area;};intarea(structrectangle*);intmain(){structrectangle s;printf("Input length and breadth of a rectangle");scanf("%f %f",&s.len,&s.brd);area(&s);return0;}intarea(structrectangle*r){
    
       r->area =(double)(r->len*r->brd);printf("Length: %f \n Breadth: %f \n Area: %lf\n", r->len, r->brd, r->area);return0;}

    Output

    Run the code and check its output −

    Input length and breadth of a rectangle
    10.5 20.5
    Length: 10.500000 
    Breadth: 20.500000 
    Area: 215.250000
    

    The logical extension of the concept of passing a pointer to a function leads to passing a Union pointer, i.e., the pointer of a multi-dimensional array, passing the pointer of a self-referential structure, etc., all these have important uses in different application areas such as complex data structures, hardware control programming, etc.

  • Character Pointers and Functions

    What is a Character Pointer in C?

    character pointer stores the address of a character type or address of the first character of a character array (string). Character pointers are very useful when you are working to manipulate the strings.

    There is no string data type in C. An array of “char” type is considered as a string. Hence, a pointer of a char type array represents a string. This char pointer can then be passed as an argument to a function for processing the string.

    Declaring a Character Pointer

    A character pointer points to a character or a character array. Thus, to declare a character pointer, use the following syntax:

    char*pointer_name;

    Initializing a Character Pointer

    After declaring a character pointer, you need to initialize it with the address of a character variable. If there is a character array, you can simply initialize the character pointer by providing the name of the character array or the address of the first elements of it.

    Character Pointer of Character

    The following is the syntax to initialize a character pointer of a character type:

    char*pointer_name =&char_variable;

    Character Pointer of Character Array

    The following is the syntax to initialize a character pointer of a character array (string):

    char*pointer_name = char_array;/*or*/char*pointer_name =&char_array[0];

    Character Pointer Example

    In the following example, we have two variables character and character array. We are taking two pointer variables to store the addresses of the character and character array, and then printing the values of the variables using the character pointers.

    #include <stdio.h>intmain(){// Declare two variableschar x ='P';char arr[]="TutorialsPoint";// Declaring character pointerschar*ptr_x =&x;char*ptr_arr = arr;// Printing valuesprintf("Value of x : %c\n",*ptr_x);printf("Value of arr: %s\n", ptr_arr);return0;}

    Output

    Run the code and check its output −

    Value of x : P
    Value of arr: TutorialsPoint
    

    Understanding Character Pointer

    A string is declared as an array as follows −

    char arr[]="Hello";

    The string is a NULL terminated array of characters. The last element in the above array is a NULL character (\0).

    Declare a pointer of char type and assign it the address of the character at the 0th position −

    char*ptr =&arr[0];

    Remember that the name of the array itself is the address of 0th element.

    char*ptr = arr;

    A string may be declared using a pointer instead of an array variable (no square brackets).

    char*ptr ="Hello";

    This causes the string to be stored in the memory, and its address stored in ptr. We can traverse the string by incrementing the ptr.

    while(*ptr !='\0'){printf("%c",*ptr);
       ptr++;}

    Accessing Character Array

    If you print a character array using the %s format specifier, you can do it by using the name of the character pointer. But if you want to access each character of the character array, you have to use an asterisk (*) before the character pointer name and then increment it.

    Example

    Here is the full program code −

    #include <stdio.h>intmain(){char arr[]="Character Pointers and Functions in C";char*ptr = arr;while(*ptr !='\0'){printf("%c",*ptr);
    
      ptr++;}}</code></pre>

    Output

    Run the code and check its output −

    Character Pointers and Functions in C
    

    Example

    Alternatively, pass ptr to printf() with %s format to print the string.

    #include <stdio.h>intmain(){char arr[]="Character Pointers and Functions in C";char*ptr = arr;printf("%s", ptr);}

    Output

    On running this code, you will get the same output −

    Character Pointers and Functions in C
    

    Character Pointer Functions

    The "string.h" header files defines a number of library functions that perform string processing such as finding the length of a string, copying a string and comparing two strings. These functions use char pointer arguments.

    The strlen() Function

    The strlen() function returns the length, i.e. the number of characters in a string. The prototype of strlen() function is as follows −

    intstrlen(char*)

    Example 1

    The following code shows how you can print the length of a string −

    #include <stdio.h>#include <string.h>intmain(){char*ptr ="Hello";printf("Given string: %s \n", ptr);printf("Length of the string: %d",strlen(ptr));return0;}

    When you run this code, it will produce the following output −

    Given string: Hello 
    Length of the string: 5
    

    Example 2

    Effectively, the strlen() function computes the string length as per the user-defined function str_len() as shown below −

    #include <stdio.h>#include <string.h>intstr_len(char*);intmain(){char*ptr ="Welcome to Tutorialspoint";int length =str_len(ptr);printf("Given string: %s \n", ptr);printf("Length of the string: %d", length);return0;}intstr_len(char*ptr){int i =0;while(*ptr !='\0'){
    
      i++;
      ptr++;}return i;}</code></pre>

    When you run this code, it will produce the following output −

    Given string: Welcome to Tutorialspoint 
    Length of the string: 25
    

    The strcpy() Function

    The assignment operator ( = ) is not used to assign a string value to a string variable, i.e., a char pointer. Instead, we need to use the strcpy() function with the following prototype −

    char*strcpy(char* dest,char* source);

    Example 1

    The following example shows how you can use the strcpy() function −

    #include <stdio.h>#include <string.h>intmain(){char*ptr ="How are you doing?";char*ptr1;strcpy(ptr1, ptr);printf("%s", ptr1);return0;}

    The strcpy() function returns the pointer to the destination string ptr1.

    How are you doing?
    

    Example 2

    Internally, the strcpy() function implements the following logic in the user-defined str_cpy() function −

    #include <stdio.h>#include <string.h>voidstr_cpy(char*d,char*s);intmain(){char*ptr ="Using the strcpy() Function";char*ptr1;str_cpy(ptr1, ptr);printf("%s", ptr1);return0;}voidstr_cpy(char*d,char*s){int i;for(i =0; s[i]!='\0'; i++)
    
      d&#91;i]= s&#91;i];
    d[i]='\0';}

    When you runt his code, it will produce the following output −

    Using the strcpy() Function
    

    The function copies each character from the source string to the destination till the NULL character "\0" is reached. After the loop, it adds a "\0" character at the end of the destination array.

    The strcmp() Function

    The usual comparison operators (<, >, <=, >=, ==, and !=) are not allowed to be used for comparing two strings. Instead, we need to use strcmp() function from the "string.h" header file. The prototype of this function is as follows −

    intstrcmp(char*str1,char*str2)

    The strcmp() function has three possible return values −

    • When both strings are found to be identical, it returns "0".
    • When the first not-matching character in str1 has a greater ASCII value than the corresponding character in str2, the function returns a positive integer. It implies that str1 appears after str2 in alphabetical order, as in a dictionary.
    • When the first not-matching character in str1 has a lesser ASCII value than the corresponding character in str2, the function returns a negative integer. It implies that str1 appears before str2 in alphabetical order, as in a dictionary.

    Example 1

    The following example demonstrates how you can use the strcmp() function in a C program −

    #include <stdio.h>#include <string.h>intmain(){char*s1 ="BASK";char*s2 ="BALL";int ret =strcmp(s1, s2);if(ret ==0)printf("Both strings are identical\n");elseif(ret >0)printf("The first string appears after the second string \n");elseprintf("The first string appears before the second string \n");return0;}

    Run the code and check its output −

    The first string appears after the second string
    

    Change s1 to BACK and run the code again. Now, you will get the following output −

    The first string appears before the second string
    

    Example 2

    You can obtain a similar result using the user-defined function str_cmp(), as shown in the following code −

    #include <stdio.h>#include <string.h>intstr_cmp(char*str1,char*str2);intmain(){char*s1 ="The Best C Programming Tutorial Available Online";char*s2 ="The Best C Programming Tutorial Available Online";int ret =str_cmp(s1, s2);if(ret ==0)printf("Both strings are identical\n");elseif(ret >0)printf("The first string appears after the second string\n");elseprintf("The first string appears before the second string\n");return0;}intstr_cmp(char*str1,char*str2){while(*str1 !='\0'&&*str2 !='\0'){if(*str1 !=*str2){return*str1 -*str2;}
    
      str1++;
      str2++;}// If both strings are equal, return 0return0;}</code></pre>

    When you run this code, it will produce the following output −

    Both strings are identical
    

    The str_cmp() function compares the characters at the same index in a string till the characters in either string are exhausted or the characters are equal.

    At the time of detecting unequal characters at the same index, the difference in their ASCII values is returned. It returns "0" when the loop is terminated.

  • Chain of Pointers

    What is Chain of Pointers in C?

    chain of pointers in C is a series of pointers that point to each other. A pointer variable can store the address of another variable which can be of any type, including another pointer, in which case it is called a pointer to pointer.

    A chain of pointers is when there are multiple levels of pointers. Theoretically, there is no limit to how many levels the chaining can be done, as shown in the following diagram −

    Chain of Pointers

    Declaration of Chain of Pointers

    This can be represented by the following code −

    int a =10;int*x =&a;int**y =&x;int***z =&y;

    In the above example, “x” is a pointer to an “int” type, as the notation “int *” indicates. To store the address of “x” in “y”, it should be a pointer to a pointer to int, i.e., “int **”.

    Similarly, “z” is a “pointer to a pointer to a pointer” to int, hence the asterisk appears thrice in its declaration, i.e., “int ***”.

    How Does the Dereferencing Work?

    We know that “*x” returns the value at the address stored in “x”, i.e., the value of “a”.

    Going by the same logic, “*y” should return its value (refer to the above diagram) which is 1000, which in turn is the address of “a”. Hence, the double dereferencing of “y” (i.e., “**y”) should give you the value of “a”.

    Further, a triple referencing of “z” as “***z” should give the value of “a”.

    Example

    The following example shows how “double dereferencing” and “triple dereferencing” work −

    #include <stdio.h>intmain(){int a =10;int*x =&a;int**y =&x;int***z =&y;printf("a: %d\n", a);printf("a: %d\n",*x);// dereferencing x;printf("a: %d\n",**y);// double dereferencing y;printf("a: %d\n",***z);// triple dereferencing z;return0;}

    Output

    Notice that all the three cases of dereferencing print the value of “a” −

    a: 10
    a: 10
    a: 10
    a: 10
    

    A Chain of Float Pointers

    We can follow the same logic to create a chain of float pointers and apply dereferencing of multiple levels to obtain the value of a float variable.

    Example

    The following example shows how you can work with a chain of float pointers −

    #include <stdio.h>intmain(){float a =10.25;float*x =&a;float**y =&x;float***z =&y;printf("a: %f\n", a);printf("a: %f\n",*x);printf("a: %f\n",**y);printf("a: %f\n",***z);return0;}

    Output

    Run the code and check its output −

    a: 10.250000
    a: 10.250000
    a: 10.250000
    a: 10.250000
    

    Updating the Original Variable by Dereferencing

    We can also update the value of the original variable by dereferencing. Take a look at the following statement −

    *x =11.25;

    It will change the value of “a” accordingly. Similarly, it can be updated with the pointer at subsequent levels.

    Example

    The following program shows how you can update the original variable using different levels of dereferencing −

    #include <stdio.h>intmain(){float a =10.25;;float*x =&a;float**y =&x;float***z =&y;printf("a: %f\n", a);// update with first pointer*x =11.25;printf("a: %f\n",*x);// update with second pointer**y =12.25;printf("a: %f\n",**y);// update with third pointer***z =13.25;printf("a: %f\n",***z);return0;}

    Output

    Run the code and check its output −

    a:10.250000
    a:11.250000
    a:12.250000
    a:13.250000
    

    A Chain of Character Pointers

    A string is represented as an array of “char” type or a pointer to “char” type −

    char*a ="Hello";

    Hence, we can create a chain of char pointers.

    Note: The only difference is, here the original variable itself is a pointer, so the upper-level pointers have one asterisk more, as compared to the earlier examples.

    Example

    The following example shows how a chain of character pointers works −

    #include <stdio.h>intmain(){char*a ="Hello";char**x =&a;char***y =&x;char****z =&y;printf("a: %s\n", a);printf("a: %s\n",*x);printf("a: %s\n",**y);printf("a: %s\n",***z);return0;}

    Output

    When you run this code, it will produce the following output −

    a: Hello
    a: Hello
    a: Hello
    a: Hello
    

    Chaining of pointers is useful for creating linked lists and other data structures.

  • Pointer to Pointer (Double Pointer)

    What is a Double Pointer in C?

    pointer to pointer which is also known as a double pointer in C is used to store the address of another pointer.

    A variable in C that stores the address of another variable is known as a pointer. A pointer variable can store the address of any type including the primary data types, arrays, struct types, etc. Likewise, a pointer can store the address of another pointer too, in which case it is called “pointer to pointer” (also called “double pointer”).

    A “pointer to a pointer” is a form of multiple indirection or a chain of pointers. Normally, a pointer contains the address of a variable. When we define a “pointer to a pointer”, the first pointer contains the address of the second pointer, which points to the location that contains the actual value as shown below −

    Pointer to Pointer

    Declaration of Pointer to a Pointer

    The declaration of a pointer to pointer (double pointer) is similar to the declaration of a pointer, the only difference is that you need to use an additional asterisk (*) before the pointer variable name.

    Example

    For example, the following declaration declares a “pointer to a pointer” of type int

    int**var;

    When a target value is indirectly pointed to by a “pointer to a pointer”, accessing that value requires that the asterisk operator be applied twice.

    Example of Pointer to Pointer (Double Pointer)

    The following example demonstrates the declaration, initialization, and using pointer to pointer (double pointer) in C:

    #include <stdio.h>intmain(){// An integer variableint a =100;// Pointer to integerint*ptr =&a;// Pointer to pointer (double pointer)int**dptr =&ptr;printf("Value of 'a' is : %d\n", a);printf("Value of 'a' using pointer (ptr) is : %d\n",*ptr);printf("Value of 'a' using double pointer (dptr) is : %d\n",**dptr);return0;}

    Output

    Value of 'a' is : 100
    Value of 'a' using pointer (ptr) is : 100
    Value of 'a' using double pointer (dptr) is : 100
    

    How Does a Normal Pointer Work in C?

    Assume that an integer variable “a” is located at an arbitrary address 1000. Its pointer variable is “b” and the compiler allocates it the address 2000. The following image presents a visual depiction −

    Normal Pointer

    Let us declare a pointer to int type and store the address of an int variable in it.

    int a =10;int*b =&a;

    The dereference operator fetches the value via the pointer.

    printf("a: %d \nPointer to 'a' is 'b': %d \nValue at 'b': %d", a, b,*b);

    Example

    Here is the complete program that shows how a normal pointer works −

    #include <stdio.h>intmain(){int a =10;int*b =&a;printf("a: %d \nPointer to 'a' is 'b': %d \nValue at 'b': %d", a, b,*b);return0;}

    Output

    It will print the value of int variable, its address, and the value obtained by the dereference pointer −

    a: 10 
    Pointer to 'a' is 'b': 6422036 
    Value at 'b': 10
    

    How Does a Double Pointer Work?

    Let us now declare a pointer that can store the address of “b”, which itself is a pointer to int type written as “int *”.

    Let’s assume that the compiler also allocates it the address 3000.

    Double Pointer

    Hence, “c” is a pointer to a pointer to int, and should be declared as “int **”.

    int**c =&b;printf("b: %d \nPointer to 'b' is 'c': %d \nValue at b: %d\n", b, c,*c);

    You get the value of “b” (which is the address of “a”), the value of “c” (which is the address of “b:), and the dereferenced value from “c” (which is the address of “a”) −

    b:6422036 
    Pointer to b is c:6422024 
    Value at b:6422036

    Here, “c” is a double pointer. The first asterisk in its declaration points to “b” and the second asterisk in turn points to “a”. So, we can use the double reference pointer to obtain the value of “a” from “c”.

    printf("Value of 'a' from 'c': %d",**c);

    This should display the value of ‘a’ as 10.

    Example

    Here is the complete program that shows how a double pointer works −

    #include <stdio.h>intmain(){int a =10;int*b =&a;printf("a: %d \nAddress of 'a': %d \nValue at a: %d\n\n", a, b,*b);int**c =&b;printf("b: %d \nPointer to 'b' is c: %d \nValue at b: %d\n", b, c,*c);printf("Value of 'a' from 'c': %d",**c);return0;}

    Output

    Run the code and check its output −

    a: 10 
    Address of 'a': 1603495332 
    Value at a: 10
    
    b: 1603495332 
    Pointer to 'b' is c: 1603495336 
    Value at b: 1603495332
    Value of 'a' from 'c': 10
    

    A Double Pointer Behaves Just Like a Normal Pointer

    A “pointer to pointer” or a “double pointer” in C behaves just like a normal pointer. So, the size of a double pointer variable is always equal to a normal pointer.

    We can check it by applying the sizeof operator to the pointers “b” and “c” in the above program −

    printf("Size of b - a normal pointer: %d\n",sizeof(b));printf("Size of c - a double pointer: %d\n",sizeof(c));

    This shows the equal size of both the pointers −

    Size of b - a normal pointer:8
    Size of c - a double pointer:8

    Note: The size and address of different pointer variables shown in the above examples may vary, as it depends on factors such as CPU architecture and the operating system. However, they will show consistent results.

    Multilevel Pointers in C (Is a Triple Pointer Possible?)

    Theoretically, there is no limit to how many asterisks can appear in a pointer declaration.

    If you do need to have a pointer to “c” (in the above example), it will be a “pointer to a pointer to a pointer” and may be declared as −

    int***d =&c;

    Mostly, double pointers are used to refer to a two−dimensional array or an array of strings.

  • Pointers and Multidimensional Arrays

    In C language, an array is a collection of values of similar type stored in continuous memory locations. Each element in an array (one-dimensional or multi-dimensional) is identified by one or more unique integer indices.

    A pointer, on the other hand, stores the address of a variable. The address of the 0th element in an array is the pointer of the array. You can use the “dereference operator” to access the value that a pointer refers to.

    You can declare a one-dimensional, two-dimensional or multi-dimensional array in C. The term “dimension” refers to the number of indices required to identify an element in a collection.

    Pointers and One-dimensional Arrays

    In a one-dimensional array, each element is identified by a single integer:

    int a[5]={1,2,3,4,5};

    Here, the number “1” is at the 0th index, “2” at index 1, and so on.

    A variable that stores the address of 0th element is its pointer −

    int*x =&a[0];

    Simply, the name of the array too points to the address of the 0th element. So, you can also use this expression −

    int*x = a;

    Example

    Since the value of the pointer increments by the size of the data type, “x++” moves the pointer to the next element in the array.

    #include <stdio.h>intmain(){int arr[]={1,2,3,4,5};int length =sizeof(arr)/sizeof(arr[0]);int i =0;int*ptr = arr;while(i < length){printf("arr[%d]: %d \n", i,*(ptr + i));
    
      i++;}return0;}</code></pre>

    Output

    When you run this code, it will produce the following output −

    arr[0]: 1
    arr[1]: 2
    arr[2]: 3
    arr[3]: 4
    arr[4]: 5
    

    Pointers and Two-dimensional Arrays

    If a one-dimensional array is like a list of elements, a two-dimensional array is like a table or a matrix.

    The elements in a 2D array can be considered to be logically arranged in rows and columns. Hence, the location of any element is decided by two indices, its row number and column number. Both row and column indexes start from "0".

    int arr[2][2];

    Such an array is represented as −

    Col0Col1Col2
    Row0arr[0][0]arr[0][1]arr[0][2]
    Row1arr[1][0]arr[1][1]arr[1][2]
    Row2arr[2][0]arr[2][1]arr[2][2]

    It may be noted that the tabular arrangement is only a logical representation. The compiler allocates a block of continuous bytes. In C, the array allocation is done in a row-major manner, which means the elements are read into the array in a row−wise manner.

    Here, we declare a 2D array with three rows and four columns (the number in the first square bracket always refers to the number of rows) as −

    int arr[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};

    The compiler will allocate the memory for the above 2D array in a row−wise order. Assuming that the first element of the array is at the address 1000 and the size of type "int" is 4 bytes, the elements of the array will get the following allocated memory locations −

    Row 0Row 1Row 2
    Value123456789101112
    Address100010041008101210161020102410281032103610401044

    We will assign the address of the first element of the array num to the pointer ptr using the address of & operator.

    int*ptr =&arr[0][0];

    Example 1

    If the pointer is incremented by 1, it moves to the next address. All the 12 elements in the "34" array can be accessed in a loop as follows −

    #include <stdio.h>intmain(){int arr[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12},};// pointer ptr pointing at array numint*ptr =&arr[0][0];int i, j, k =0;// print the elements of the array num via pointer ptrfor(i =0; i <3; i++){for(j =0; j <4; j++){printf("%d   ",*(ptr + k));
    
         k++;}printf("\n");}return0;}</code></pre>

    Output

    When you run this code, it will produce the following output −

    1   2   3   4   
    5   6   7   8   
    9   10   11   12
    

    In general, the address of any element of the array by with the use the following formula −

    add of element at ith row and jth col = baseAddress +[(i * no_of_cols + j)*sizeof(array_type)]

    In our 34 array,

    add of arr[2][4]=1000+(2*4+2)*4=1044

    You can refer to the above figure and it confirms that the address of "arr[3][4]" is 1044.

    Example 2

    Use the dereference pointer to fetch the value at the address. Let us use this formula to traverse the array with the help of its pointer −

    #include <stdio.h>intmain(){// 2d arrayint arr[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};int ROWS =3, COLS =4;int i, j;// pointerint*ptr =&arr[0][0];// print the element of the array via pointer ptrfor(i =0; i < ROWS; i++){for(j =0; j < COLS; j++){printf("%4d ",*(ptr +(i * COLS + j)));}printf("\n");}return0;}

    Output

    When you run this code, it will produce the following output −

       1    2    3    4
       5    6    7    8
       9   10   11   12
    

    Pointers and Three-dimensional Arrays

    A three-dimensional array is an array of two-dimensional arrays. Such an array is declared with three subscripts −

    int arr [x][y][j];

    This array can be considered as "x" number of layers of tables, each table having "x" rows and "y" number of columns.

    An example of a 3D array is −

    int arr[3][3][3]={{{11,12,13},{14,15,16},{17,18,19}},{{21,22,23},{24,25,26},{27,28,29}},{{31,32,33},{34,35,36},{37,38,39}},};

    A pointer to the 3D array can be declared as −

    int* ptr =&arr[0][0][0];

    Knowing that, the name of the array itself is the address of 0th element, we can write the pointer of a 3D array as −

    int* ptr = arr;

    Each layer of "x" rows and "y" columns occupies −

    x * y *sizeof(data_type)

    Number of bytes. Assuming that the memory allocated to the 3D array "arr" as declared above starts from the address 1000, the second layer (with "i = 1") starts at 1000 + (3 3) 4 = 1036 byte position.

    ptr = Base address of 3D array arr 
    

    If JMAX is the number of rows and KMAX is the number of columns, then the address of the element at the 0th row and the 0th column of the 1st slice is −

    arr[1][0][0]= ptr +(1* JMAX * KMAX)

    The formula to obtain the value of an element at the jth row and kth column of the ith slice can be given as −

    arr[i][j][k]=*(ptr +(i * JMAX*KMAX)+(j*KMAX + k))

    Example: Printing a 3D Array using Pointer Dereferencing

    Let us use this formula to print the 3D array with the help of the pointer dereferencing −

    #include <stdio.h>intmain(){int i, j, k;int arr[3][3][3]={{{11,12,13},{14,15,16},{17,18,19}},{{21,22,23},{24,25,26},{27,28,29}},{{31,32,33},{34,35,36},{37,38,39}},};int JMAX =3, KMAX =3;int*ptr = arr;// &arr[0][0][0];for(i =0; i <3; i++){for(j =0; j <3; j++){for(k =0; k <3; k++){printf("%d ",*(ptr+(i*JMAX*KMAX)+(j*KMAX+k)));}printf("\n");}printf("\n");}return0;}

    Output

    When you run this code, it will produce the following output −

    11 12 13 
    14 15 16 
    17 18 19 
    
    21 22 23 
    24 25 26 
    27 28 29 
    
    31 32 33 
    34 35 36 
    37 38 39
    

    In general, accessing an array with a pointer is quite similar to accessing an array with subscript representation. The main difference between the two is that the subscripted declaration of an array allocates the memory statically, whereas we can use pointers for dynamic memory allocation.

    To pass a multi-dimensional array to a function, you need to use pointers instead of subscripts. However, using a subscripted array is more convenient than using pointers, which can be difficult for new learners.

  • Array of Pointers

    What is an Array of Pointers?

    Just like an integer array holds a collection of integer variables, an array of pointers would hold variables of pointer type. It means each variable in an array of pointers is a pointer that points to another address.

    The name of an array can be used as a pointer because it holds the address to the first element of the array. If we store the address of an array in another pointer, then it is possible to manipulate the array using pointer arithmetic.

    Create an Array of Pointers

    To create an array of pointers in C language, you need to declare an array of pointers in the same way as a pointer declaration. Use the data type then an asterisk sign followed by an identifier (array of pointers variable name) with a subscript ([]) containing the size of the array.

    In an array of pointers, each element contains the pointer to a specific type.

    Example of Creating an Array of Pointers

    The following example demonstrates how you can create and use an array of pointers. Here, we are declaring three integer variables and to access and use them, we are creating an array of pointers. With the help of an array of pointers, we are printing the values of the variables.

    #include <stdio.h>intmain(){// Declaring integersint var1 =1;int var2 =2;int var3 =3;// Declaring an array of pointers to integersint*ptr[3];// Initializing each element of// array of pointers with the addresses of// integer variables
      ptr[0]=&var1;
      ptr[1]=&var2;
      ptr[2]=&var3;// Accessing valuesfor(int i =0; i <3; i++){printf("Value at ptr[%d] = %d\n", i,*ptr[i]);}return0;}

    Output

    When the above code is compiled and executed, it produces the following result −

    Value of var[0] = 10
    Value of var[1] = 100
    Value of var[2] = 200
    

    There may be a situation when we want to maintain an array that can store pointers to an “int” or “char” or any other data type available.

    An Array of Pointers to Integers

    Here is the declaration of an array of pointers to an integer −

    int*ptr[MAX];

    It declares ptr as an array of MAX integer pointers. Thus, each element in ptr holds a pointer to an int value.

    Example

    The following example uses three integers, which are stored in an array of pointers, as follows −

    #include <stdio.h>constint MAX =3;intmain(){int var[]={10,100,200};int i,*ptr[MAX];for(i =0; i < MAX; i++){
    
      ptr&#91;i]=&amp;var&#91;i];/* assign the address of integer. */}for(i =0; i &lt; MAX; i++){printf("Value of var&#91;%d] = %d\n", i,*ptr&#91;i]);}return0;}</code></pre>

    Output

    When the above code is compiled and executed, it produces the following result −

    Value of var[0] = 10
    Value of var[1] = 100
    Value of var[2] = 200
    

    An Array of Pointers to Characters

    You can also use an array of pointers to character to store a list of strings as follows −

    #include <stdio.h>constint MAX =4;intmain(){char*names[]={"Zara Ali","Hina Ali","Nuha Ali","Sara Ali"};int i =0;for(i =0; i < MAX; i++){printf("Value of names[%d] = %s\n", i, names[i]);}return0;}

    Output

    When the above code is compiled and executed, it produces the following result −

    Value of names[0] = Zara Ali
    Value of names[1] = Hina Ali
    Value of names[2] = Nuha Ali
    Value of names[3] = Sara Ali
    

    An Array of Pointers to Structures

    When you have a list of structures and want to manage it using a pointer. You can declare an array of structures to access and manipulate the list of structures.

    Example

    The below example demonstrates the use of an array of pointers to structures.

    #include <stdio.h>#include <stdlib.h>#include <string.h>// Declaring a structuretypedefstruct{char title[50];float price;} Book;constint MAX =3;intmain(){
      Book *book[MAX];// Initialize each book (pointer)for(int i =0; i < MAX; i++){
    
    book&#91;i]=malloc(sizeof(Book));snprintf(book&#91;i]-&gt;title,50,"Book %d", i +1);
    book&#91;i]-&gt;price =100+ i;}// Print details of each bookfor(int i =0; i &lt; MAX; i++){printf("Title: %s, Price: %.2f\n", book&#91;i]-&gt;title, book&#91;i]-&gt;price);}// Free allocated memoryfor(int i =0; i &lt; MAX; i++){free(book&#91;i]);}return0;}</code></pre>

    Output

    When the above code is compiled and executed, it produces the following result −

    Title: Book 1, Price: 100.00
    Title: Book 2, Price: 101.00
    Title: Book 3, Price: 102.00
    
  • Pointer to an Array

    An array name is a constant pointer to the first element of the array. Therefore, in this declaration,

    int balance[5];

    balance is a pointer to &balance[0], which is the address of the first element of the array.

    Example

    In this code, we have a pointer ptr that points to the address of the first element of an integer array called balance.

    #include <stdio.h>intmain(){int*ptr;int balance[5]={1,2,3,4,5};
    
       ptr = balance;printf("Pointer 'ptr' points to the address: %d", ptr);printf("\nAddress of the first element: %d", balance);printf("\nAddress of the first element: %d",&balance[0]);return0;}

    Output

    In all the three cases, you get the same output −

    Pointer 'ptr' points to the address: 647772240
    Address of the first element: 647772240
    Address of the first element: 647772240
    

    If you fetch the value stored at the address that ptr points to, that is *ptr, then it will return 1.

    Array Names as Constant Pointers

    It is legal to use array names as constant pointers and vice versa. Therefore, *(balance + 4) is a legitimate way of accessing the data at balance[4].

    Once you store the address of the first element in “ptr“, you can access the array elements using *ptr*(ptr + 1)*(ptr + 2), and so on.

    Example

    The following example demonstrates all the concepts discussed above −

    #include <stdio.h>intmain(){/* an array with 5 elements */double balance[5]={1000.0,2.0,3.4,17.0,50.0};double*ptr;int i;
    
       ptr = balance;/* output each array element's value */printf("Array values using pointer: \n");for(i =0; i <5; i++){printf("*(ptr + %d): %f\n",  i,*(ptr + i));}printf("\nArray values using balance as address:\n");for(i =0; i <5; i++){printf("*(balance + %d): %f\n",  i,*(balance + i));}return0;}

    Output

    When you run this code, it will produce the following output −

    Array values using pointer:
    *(ptr + 0): 1000.000000
    *(ptr + 1): 2.000000
    *(ptr + 2): 3.400000
    *(ptr + 3): 17.000000
    *(ptr + 4): 50.000000
    
    Array values using balance as address:
    *(balance + 0): 1000.000000
    *(balance + 1): 2.000000
    *(balance + 2): 3.400000
    *(balance + 3): 17.000000
    *(balance + 4): 50.000000
    

    In the above example, ptr is a pointer that can store the address of a variable of double type. Once we have the address in ptr*ptr will give us the value available at the address stored in ptr.

  • Pointer vs Array in C

    Arrays and Pointers are two important language constructs in C, associated with each other in many ways. In many cases, the tasks that you perform with a pointer can also be performed with the help of an array.

    However, there are certain conceptual differences between arrays and pointers. Read this chapter to understand their differences and comparative advantages and disadvantages.

    Arrays in C

    In a C program, an array is an indexed collection of elements of similar type, stored in adjacent memory locations.

    To declare an array, we use the following syntax −

    data_type arr_name [size];

    The size should be a non-negative integer. For example −

    int arr[5];

    The array can be initialized along with the declaration, with the elements given as a comma-separated list inside the curly brackets. Mentioning its size is optional.

    int arr[]={1,2,3,4,5};

    Each element in an array is characterized by a unique integral index, starting from “0”. In C language, the lower bound of an array is always “0” and the upper bound is “size 1”.

    Example of an Array

    The following example shows how you can traverse an array with indexed subscripts −

    #include <stdio.h>intmain(){/* an array with 5 elements */int arr[5]={10,20,30,40,50};int i;/* output each array element's value */printf("Array values with subscripts: \n");for(i =0; i <5; i++){printf("arr[%d]: %d\n", i, arr[i]);}return0;}

    Output

    When you run this code, it will produce the following output −

    Array values with subscripts:
    arr[0]: 10
    arr[1]: 20
    arr[2]: 30
    arr[3]: 40
    arr[4]: 50
    

    Pointers in C

    C allows you to access the memory location of a variable that has been randomly allocated by the compiler. The address−of operator (&) returns the address of the variable.

    A variable that stores the address of another variable is called a pointer. The type of the pointer must be the same as the one whose address it stores.

    To differentiate from the target variable type, the name of the pointer is prefixed with an asterisk (*). If we have an int variable, its pointer is declared as “int *”.

    int x =5;int*y =&a;

    Note: In case of an array, the address of its 0th element is assigned to the pointer.

    int arr[]={1,2,3,4,5};int*ptr =&arr[0];

    In fact, the name of the array itself resolves to the address of the 0th element.

    Pointer vs Array

    Hence, we can as well write −

    int*ptr = arr;

    Since the elements of an array are placed in adjacent memory locations and the address of each subscript increments by 4 (in case of an int array), we can use this feature to traverse the array elements with the help of pointer as well.

    Example of a Pointer

    The following example shows how you can traverse an array with a pointer −

    #include <stdio.h>intmain(){/* an array with 5 elements */int arr[5]={10,20,30,40,50};int*x = arr;int i;/* output each array element's value */printf("Array values with pointer: \n");for(i =0; i <5; i++){printf("arr[%d]: %d\n", i,*(x+i));}return0;}

    Output

    Run the code and check its output −

    Array values with pointer
    arr[0]: 10
    arr[1]: 20
    arr[2]: 30
    arr[3]: 40
    arr[4]: 50
    

    Difference between Arrays and Pointers in C

    The following table highlights the important differences between arrays and pointers −

    ArrayPointer
    It stores the elements of a homogeneous data type in adjacent memory locations.It stores the address of a variable, or an array
    An array is defined as a collection of similar datatypes.A pointer is a variable that stores address of another variable.
    The number of variables that can be stored is decided by the size of the array.A pointer can store the address of only a single variable.
    The initialization of arrays can be done while defining them.Pointers cannot be initialized while defining them.
    The nature of arrays is static.The nature of pointers is dynamic.
    Arrays cannot be resized according to the user’s requirements.Pointers can be resized at any point in time.
    The allocation of an array is done at compile time.The allocation of the pointer is done at run time.
  • Pointers and Arrays

    In C programming, the concepts of arrays and pointers have a very important role. There is also a close association between the two. In this chapter, we will explain in detail the relationship between arrays and pointers in C programming.

    Arrays in C

    An array in C is a homogenous collection of elements of a single data type stored in a continuous block of memory. The size of an array is an integer inside square brackets, put in front of the name of the array.

    Declaring an Array

    To declare an array, the following syntax is used −

    data_type arr_name[size];

    Each element in the array is identified by a unique incrementing index, starting from “0”. An array can be declared and initialized in different ways.

    You can declare an array and then initialize it later in the code, as and when required. For example −

    int arr[5];...... 
    a[0]=1;
    a[1]=2;......

    You can also declare and initialize an array at the same time. The values to be stored are put as a comma separated list inside curly brackets.

    int a[5]={1,2,3,4,5};

    Note: When an array is initialized at the time of declaration, mentioning its size is optional, as the compiler automatically computes the size. Hence, the following statement is also valid −

    int a[]={1,2,3,4,5};

    Example: Lower Bound and Upper Bound of an Array

    All the elements in an array have a positional index, starting from “0”. The lower bound of the array is always “0”, whereas the upper bound is “size − 1”. We can use this property to traverse, assign, or read inputs into the array subscripts with a loop.

    Take a look at this following example −

    #include <stdio.h>intmain(){int a[5], i;for(i =0; i <=4; i++){scanf("%d",&a[i]);}for(i =0; i <=4; i++){printf("a[%d] = %d\n",i,  a[i]);}return0;}

    Output

    Run the code and check its output −

    a[0] = 712952649
    a[1] = 32765
    a[2] = 100
    a[3] = 0
    a[4] = 4096
    

    Pointers in C

    A pointer is a variable that stores the address of another variable. In C, the symbol (&) is used as the address-of operator. The value returned by this operator is assigned to a pointer.

    To declare a variable as a pointer, you need to put an asterisk (*) before the name. Also, the type of pointer variable must be the same as the type of the variable whose address it stores.

    In this code snippet, “b” is an integer pointer that stores the address of an integer variable “a” −

    int a =5;int*b =&a;

    In case of an array, you can assign the address of its 0th element to the pointer.

    int arr[]={1,2,3,4,5};int*b =&arr[0];

    In C, the name of the array itself resolves to the address of its 0th element. It means, in the above case, we can use “arr” as equivalent to “&[0]”:

    int*b = arr;

    Example: Increment Operator with Pointer

    Unlike a normal numeric variable (where the increment operator “++” increments its value by 1), the increment operator used with a pointer increases its value by the sizeof its data type.

    Hence, an int pointer, when incremented, increases by 4.

    #include <stdio.h>intmain(){int a =5;int*b =&a;printf("Address of a: %d\n", b);
       b++;printf("After increment, Address of a: %d\n", b);return0;}

    Output

    Run the code and check its output −

    Address of a: 6422036
    After increment, Address of a: 6422040
    

    The Dereference Operator in C

    In C, the “*” symbol is used as the dereference operator. It returns the value stored at the address to which the pointer points.

    Hence, the following statement returns “5”, which is the value stored in the variable “a”, the variable that “b” points to.

    int a =5;int*b =&a;printf("value of a: %d\n",*b);

    Note: In case of a char pointer, it will increment by 1; in case of a double pointer, it will increment by 8; and in case of a struct type, it increments by the sizeof value of that struct type.

    Example: Traversing an Array Using a Pointer

    We can use this property of the pointer to traverse the array element with the help of a pointer.

    #include <stdio.h>intmain(){int arr[5]={1,2,3,4,5};int*b = arr;printf("Address of a[0]: %d value at a[0] : %d\n",b,*b);
    
    b++;printf("Address of a[1]: %d value at a[1] : %d\n", b,*b); b++;printf("Address of a[2]: %d value at a[2] : %d\n", b,*b); b++;printf("Address of a[3]: %d value at a[3] : %d\n", b,*b);
    b++;printf("Address of a[4]: %d value at a[4] : %d\n", b,*b);return0;}

    Output

    Run the code and check its output −

    address of a[0]: 6422016 value at a[0] : 1
    address of a[1]: 6422020 value at a[1] : 2
    address of a[2]: 6422024 value at a[2] : 3
    address of a[3]: 6422028 value at a[3] : 4
    address of a[4]: 6422032 value at a[4] : 5
    

    Points to Note

    It may be noted that −

    • “&arr[0]” is equivalent to “b” and “arr[0]” to “*b”.
    • Similarly, “&arr[1]” is equivalent to “b + 1” and “arr[1]” is equivalent to “*(b + 1)”.
    • Also, “&arr[2]” is equivalent to “b + 2” and “arr[2]” is equivalent to “*(b+2)”.
    • In general, “&arr[i]” is equivalent to “b + I” and “arr[i]” is equivalent to “*(b+i)”.

    Example: Traversing an Array using the Dereference Operator

    We can use this property and use a loop to traverse the array with the dereference operator.

    #include <stdio.h>intmain(){int arr[5]={1,2,3,4,5};int*b = arr;int i;for(i =0; i <=4; i++){printf("a[%d] = %d\n",i,*(b+i));}return0;}

    Output

    Run the code and check its output −

    a[0] = 1
    a[1] = 2
    a[2] = 3
    a[3] = 4
    a[4] = 5
    

    You can also increment the pointer in every iteration and obtain the same result −

    for(i =0; i <=4; i++){printf("a[%d] = %d\n", i,*b);
       b++;}

    The concept of arrays and pointers in C has a close relationship. You can use pointers to enhance the efficiency of a program, as pointers deal directly with the memory addresses. Pointers can also be used to handle multi−dimensional arrays.

  • Pointer Arithmetics

    A pointer variable in C stores the address of another variable. The address is always an integer. So, can we perform arithmetic operations such as addition and subtraction on the pointers? In this chapter, we will explain which arithmetic operators use pointers in C as operands, and which operations are not defined to be performed with pointers.

    C pointers arithmetic operations are different from the general arithmetic operations. The following are some of the important pointer arithmetic operations in C:

    • Increment and Decrement of a Pointer
    • Addition and Subtraction of Integer to Pointer
    • Subtraction of Pointers
    • Comparison of Pointers

    Let us discuss all these pointer arithmetic operations in detail with the help of examples.

    Increment and Decrement of a Pointer

    We know that “++” and “–” are used as the increment and decrement operators in C. They are unary operators, used in prefix or postfix manner with numeric variable operands, and they increment or decrement the value of the variable by one.

    Assume that an integer variable “x” is created at address 1000 in the memory, with 10 as its value. Then, “x++” makes the value of “x” as 11.

    int x =10;// created at address 1000
    
    x++;// x becomes 11

    What happens if we declare “y” as pointer to “x” and increment “y” by 1 (with “y++”)? Assume that the address of “y” itself is 2000.

    int x =10;// created at address 1000// "y" is created at address 2000 // it holds 1000 (address of "x")int*y =&x ;
    
    y++;// y becomes 1004

    Since the variable “y” stores 1000 (the address of “x”), we expect it to become 1001 because of the “++” operator, but it increments by 4, which is the size of “int” variable.

    The is why because, if the address of “x” is 1000, then it occupies 4 bytes: 1000, 1001, 1002 and 1003. Hence, the next integer can be put only in 1004 and not before it. Hence “y” (the pointer to “x”) becomes 1004 when incremented.

    Example of Incrementing a Pointer

    The following example shows how you can increment a pointer −

    #include <stdio.h>intmain(){int x =10;int*y =&x;printf("Value of y before increment: %d\n", y);
    
       y++;printf("Value of y after increment: %d", y);}

    Output

    Run the code and check its output −

    Value of y before increment: 6422036
    Value of y after increment: 6422040
    

    You can see that the value has increased by 4. Similarly, the “–” operator decrements the value by the size of the data type.

    Example of Decrementing a Pointer

    Let us change the types of “x” and “y” to “double” and “float” and see the effect of decrement operator.

    #include <stdio.h>intmain(){double x =10;double*y =&x;printf("value of y before decrement: %ld\n", y);
       
       y--;printf("value of y after decrement: %ld", y);}

    Output

    Value of y before decrement: 6422032
    Value of y after decrement: 6422024
    

    When an array is declared, the elements are stored in adjacent memory locations. In case of “int” array, each array subscript is placed apart by 4 bytes, as the following figure shows −

    Memory Locations

    Hence, if a variable stores the address of 0th element of the array, then the “increment” takes it to the 1st element.

    Example of Traversing an Array by Incrementing Pointer

    The following example shows how you can traverse an array by incrementing a pointer successively −

    #include <stdio.h>intmain(){int a[]={10,20,30,40,50,60,70,80,90,100};int len =sizeof(a)/sizeof(int);int*x = a;int i =0;for(i =0; i < len; i++){printf("Address of subscript %d = %d Value = %d\n", i, x,*x);
    
      x++;}return0;}</code></pre>

    Output

    Run the code and check its output −

    Address of subscript 0 = 6421984 Value = 10
    Address of subscript 1 = 6421988 Value = 20
    Address of subscript 2 = 6421992 Value = 30
    Address of subscript 3 = 6421996 Value = 40
    Address of subscript 4 = 6422000 Value = 50
    Address of subscript 5 = 6422004 Value = 60
    Address of subscript 6 = 6422008 Value = 70
    Address of subscript 7 = 6422012 Value = 80
    Address of subscript 8 = 6422016 Value = 90
    Address of subscript 9 = 6422020 Value = 100
    

    Addition and Subtraction of Integer to Pointer

    An integer value can be added and subtracted to a pointer. When an integer is added to a pointer, the pointer points to the next memory address. Similarly, when an integer is subtracted from a pointer, the pointer points to the previous memory location.

    Addition and subtraction of an integer to a pointer does not add and subtract that value to the pointer, multiplication with the size of the data type is added or subtracted to the pointer.

    For example, there is an integer pointer variable ptr and it is pointing to an address 123400, if you add 1 to the ptr (ptr+1), it will point to the address 123404 (size of an integer is 4).

    Let's evaluate it,

    ptr = 123400 
    ptr = ptr + 1
    ptr = ptr + sizeof(int)*1
    ptr = 123400 + 4
    ptr = 123404
    

    Example of Adding Value to a Pointer

    In the following example, we are declaring an array and pointer to an array. Initializing the pointer with the first element of the array and then adding an integer value (2) to the pointer to get the third element of the array.

    #include <stdio.h>intmain(){int int_arr[]={12,23,45,67,89};int*ptrArr = int_arr;printf("Value at ptrArr: %d\n",*ptrArr);// Adding 2 in ptrArr
      ptrArr = ptrArr +2;printf("Value at ptrArr after adding 2: %d\n",*ptrArr);return0;}

    Output

    Value at ptrArr: 12
    Value at ptrArr after adding 2: 45
    

    Example of Subtracting Value to a Pointer

    In the following example, we are declaring an array and pointer to an array. Initializing the pointer with the last element of the array and then subtracting an integer value (2) from the pointer to get the third element of the array.

    #include <stdio.h>intmain(){int int_arr[]={12,23,45,67,89};int*ptrArr =&int_arr[4];// points to last elementprintf("Value at ptrArr: %d\n",*ptrArr);// Subtracting 2 in ptrArr
      ptrArr = ptrArr -2;printf("Value at ptrArr after adding 2: %d\n",*ptrArr);return0;}

    Output

    Value at ptrArr: 89
    Value at ptrArr after adding 2: 45
    

    Subtraction of Pointers

    We are familiar with the "+" and "−" operators when they are used with regular numeric operands. However, when you use these operators with pointers, they behave in a little different way.

    Since pointers are fairly large integers (especially in modern 64-bit systems), addition of two pointers is meaningless. When we add a 1 to a pointer, it points to the next location where an integer may be stored. Obviously, when we add a pointer (itself a large integer), the location it points may not be in the memory layout.

    However, subtraction of two pointers is realistic. It returns the number of data types that can fit in the two pointers.

    Example of Subtracting Two Pointers

    Let us take the array in the previous example and perform the subtraction of pointers of a[0] and a[9]

    #include <stdio.h>intmain(){int a[]={10,20,30,40,50,60,70,80,90,100};int*x =&a[0];// zeroth elementint*y =&a[9];// last elementprintf("Add of a[0]: %ld add of a[9]: %ld\n", x, y);printf("Subtraction of two pointers: %ld", y-x);}

    Output

    Run the code and check its output −

    Add of a[0]: 140729162482768 add of a[9]: 140729162482804
    Subtraction of two pointers: 9
    

    It can be seen that the numerical difference between the two integers is 36; it suggests that the subtraction is 9, because it can accommodate 9 integers between the two pointers.

    Comparison of Pointers

    Pointers may be compared by using relational operators such as "==", "<", and ">". If "p1" and "p2" point to variables that are related to each other (such as elements of the same array), then "p1" and "p2" can be meaningfully compared.

    Example of Comparing Pointers

    In the following example, we are declaring two pointers and initializing them with the first and last elements of the array respectively. We will keep incrementing the first variable pointer as long as the address to which it points is either less than or equal to the address of the last element of the array, which is "&var[MAX 1]" (i.e., the second pointer).

    #include <stdio.h>constint MAX =3;intmain(){int var[]={10,100,200};int i,*ptr1,*ptr2;// Initializing pointers
      ptr1 = var;
      ptr2 =&var[MAX -1];while(ptr1 <= ptr2){printf("Address of var[%d] = %p\n", i, ptr1);printf("Value of var[%d] = %d\n", i,*ptr1);/* point to the previous location */
    
    ptr1++;
    i++;}return0;}</code></pre>

    Output

    Run the code and check its output −

    Address of var[0] = 0x7ffe7101498c
    Value of var[0] = 10
    Address of var[1] = 0x7ffe71014990
    Value of var[1] = 100
    Address of var[2] = 0x7ffe71014994
    Value of var[2] = 200