Difference between Pointers, const type * pname, type * const pname, and const type * const pname in C

Question: What is the Difference Between Various Pointers, const type * pname, type * const pname, and const type * const pname in C

Answer: We are already familiar with symbolic constants created using ‘const’ keyword. For example:

/* sym_const.c -- Program creates and accesses symbolic constant */
#include <stdio.h>
 
int main(void)
{
    const int gz = 122;    /* gz is a symbolic constant */
 
    gz = 111; 		   /* What? If allowed? */
    return 0;
}

Output as below:

sym_const1.c: In function ‘main’:
sym_const1.c:8:2: error: assignment of read-only variable ‘gz’

Notice what happened when we tried to modify constant integer ‘gz’ with new value, here, 111. It caused an ERROR stating “assignment of read-only variable ‘gz’”. Actually, when we declare some variable to be constant, it’s allocated storage in read-only area of memory allocated to our program. Hence, we can’t modify constants.

Undoubtedly, we can also create symbolic constants using #define statements. O key, now, Let’s further unravel the use of ‘const’ keyword through more examples:

advertisement
advertisement
/*
 * use_const_keyword1.c -- Program shows if we can modify 
 * non-constant data using pointer to constant data
 */
#include <stdio.h>
#define MONTHS 12     /* MONTHS, a symbolic constant */
 
int main(void)
{
    double rainfall[MONTHS] = {2.12, 3.1, 0.34, 4.00, 1.1, 1.23, 2.345,
                               3.121, 3.232, 0.023, 1.023, 2.234};
 
    const double *dp = rainfall; /* dp, pointer to constant double, assigned
                                  * address of first element of rainfall */
 
    *dp = 3.12; 	         /* modifying rainfall[0], if allowed? */
    rainfall[0] = 3.12;          /* if allowed */
    rainfall[2] = 2.22;          /* if allowed */
 
    return 0;
}

Output when run on Linux,

use_const_keyword1.c: In function ‘main’:
use_const_keyword1.c:17:2: error: assignment of read-only location ‘*dp’

Remember that a pointer to constant can be made to point constant as well as non constant data. Here, in the above ex. rainfall is non-constant data and address of first element i.e. &rainfall[0] is assigned to ‘dp’. Note here that since ‘dp’ is pointer to constant data of type double, can’t be used to modify the data. However, in rainfall, an array of non-constant doubles, we can modify values of its elements.

Actually, pointer to constant is normally used as a formal argument in a function for actual array argument in order to protect values of array elements from accidental alterations. For example:

#include <stdio.h>
void show(const double *);    /* use of const with formal arg */
 
int main(void)
{
    ----
    ----
    show(rainfall);
    return 0;
}
 
void show(const double *srf)
{
    double rfd; 
    while (( rfd = *srf++) != 0)
        printf("%lf\t", rfd);
 
    printf("\n");
}

Here, in the above ex., pointer ‘srf’ to constant double data prevents actual values in array rainfall from modifications.

In the following fragment of code, although, pointer ‘dp’ is pointing to first element of the array rainfall, we can cause it to point to any element of the rainfall or to any other data of type double. Let’s see an example:

    double race_miles = 10.0;
    double rainfall[MONTHS] = {2.12, 3.1, 0.34, 4.00, 1.1, 1.23, 2.345,
                               3.121, 3.232, 0.023, 1.023, 2.234};
 
    double *dp = rainfall;    /* dp points to rainfall[0] */
    dp = &rainfall[5];        /* if allowed? */
    dp = &race_miles;	      /* if allowed? */
    /* dp points to where variable race_mile is stored */
 
    /* now modified 'dp' to pointer-to-const-double */
    const double *dp = rainfall; /* dp points to constant data */
    /* dp assigned the address of first element of rainfall */
 
    dp = &rainfall[2];	      /* if allowed? */

O key, let’s see, in the following example, if we can cause pointer ‘dp’ to point to some other location than the location/address it was initially assigned to it.

advertisement
    double rainfall[MONTHS] = {2.12, 3.1, 0.34, 4.00, 1.1, 1.23, 2.345,
                               3.121, 3.232, 0.023, 1.023, 2.234};
 
    double * const dp = rainfall;
    /* dp assigned the address of first element of rainfall */
 
    dp = &rainfall[2];	/* if allowed? */

In the above fragment of code, ‘dp’, a constant pointer is initialized with address of first element of array rainfall. It can’t be made to point elsewhere other than it was originally initialized to point to.

Now, we can use const keyword twice to cause pointer to point to constant or non constant data and the address it was originally initialized with. For example:

    double rainfall[MONTHS] = {2.12, 3.1, 0.34, 4.00, 1.1, 1.23, 2.345,
                               3.121, 3.232, 0.023, 1.023, 2.234};
 
    const double * const dp = rainfall;
    /* dp assigned the address of first element of rainfall */
 
    dp[0] = 0.123;	  /* if allowed */
    dp[4] = 2.123;	  /* if allowed */
    dp = &rainfall[2];    /* if allowed? */

Of course, in above ex., pointer ‘dp’ is a constant pointer to constant data, therefore, can neither be used to modify the values of any array location nor can be used to point to any other location or other data of type double.

advertisement

Sanfoundry Global Education & Learning Series – 1000 C Tutorials.

If you wish to look at all C Tutorials, go to C Tutorials.

If you find any mistake above, kindly email to [email protected]

advertisement
advertisement
Subscribe to our Newsletters (Subject-wise). Participate in the Sanfoundry Certification contest to get free Certificate of Merit. Join our social networks below and stay updated with latest contests, videos, internships and jobs!

Youtube | Telegram | LinkedIn | Instagram | Facebook | Twitter | Pinterest
Manish Bhojasia - Founder & CTO at Sanfoundry
Manish Bhojasia, a technology veteran with 20+ years @ Cisco & Wipro, is Founder and CTO at Sanfoundry. He lives in Bangalore, and focuses on development of Linux Kernel, SAN Technologies, Advanced C, Data Structures & Alogrithms. Stay connected with him at LinkedIn.

Subscribe to his free Masterclasses at Youtube & discussions at Telegram SanfoundryClasses.