The qualifier const can be applied to the declaration of any variable to specify that its value will not be changed (which depends upon where const variables are stored, we may change the value of the const variable by using a pointer). The result is implementation-defined if an attempt is made to change a const.
Using the const qualifier in C is a good practice when we want to ensure that some values should remain constant and should not be accidentally modified.
In C programming, the const qualifier can be used in different contexts to provide various behaviors. Here are some different use cases of the const qualifier in C:
1. Constant Variables
const int var = 100;
In this case, const is used to declare a variable var as a constant with an initial value of 100. The value of this variable cannot be modified once it is initialized. See the following example:
C
#include <stdio.h>
int main()
{
const int var = 100;
var = 200;
return 0;
}
|
Output
./Solution.cpp: In function 'int main()':
./Solution.cpp:11:9: error: assignment of read-only variable 'var'
var = 200;
^
2. Pointer to Constant
const int* ptr;
OR
int const *ptr;
We can change the pointer to point to any other integer variable, but cannot change the value of the object (entity) pointed using pointer ptr. The pointer is stored in the read-write area (stack in the present case). The object pointed may be in the read-only or read-write area. Let us see the following examples.
Example 1:
C
#include <stdio.h>
int main( void )
{
int i = 10;
int j = 20;
const int * ptr = &i;
printf ( "ptr: %d\n" , *ptr);
*ptr = 100;
ptr = &j;
printf ( "ptr: %d\n" , *ptr);
return 0;
}
|
Output
./Solution.c: In function 'main':
./Solution.c:12:10: error: assignment of read-only location '*ptr'
*ptr = 100;
^
Example 2: Program where variable i itself is constant.
C
#include <stdio.h>
int main( void )
{
int const i = 10;
int j = 20;
int const * ptr = &i;
printf ( "ptr: %d\n" , *ptr);
*ptr = 100;
ptr = &j;
printf ( "ptr: %d\n" , *ptr);
return 0;
}
|
Output
./Solution.c: In function 'main':
./Solution.c:18:10: error: assignment of read-only location '*ptr'
*ptr = 100;
^
Down qualification is not allowed in C++ and may cause warnings in C. Down qualification refers to the situation where a qualified type is assigned to a non-qualified type.
Example 3: Program to show down qualification.
C
#include <stdio.h>
int main( void )
{
int i = 10;
int const j = 20;
int * ptr = &i;
printf ( "*ptr: %d\n" , *ptr);
ptr = &j;
printf ( "*ptr: %d\n" , *ptr);
return 0;
}
|
Output
main.c: In function ‘main’:
main.c:16:9: warning: assignment discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
16 | ptr = &j;
| ^
*ptr: 10
*ptr: 20
3. Constant Pointer to Variable
int* const ptr;
The above declaration is a constant pointer to an integer variable, which means we can change the value of the object pointed by the pointer, but cannot change the pointer to point to another variable.
Example
C
#include <stdio.h>
int main( void )
{
int i = 10;
int j = 20;
int * const ptr = &i;
printf ( "ptr: %d\n" , *ptr);
*ptr = 100;
printf ( "ptr: %d\n" , *ptr);
ptr = &j;
return 0;
}
|
Output
./Solution.c: In function 'main':
./Solution.c:15:9: error: assignment of read-only variable 'ptr'
ptr = &j; /* error */
^
4. Constant Pointer to Constant
const int* const ptr;
The above declaration is a constant pointer to a constant variable which means we cannot change the value pointed by the pointer as well as we cannot point the pointer to other variables. Let us see with an example.
C
#include <stdio.h>
int main( void )
{
int i = 10;
int j = 20;
const int * const ptr = &i;
printf ( "ptr: %d\n" , *ptr);
ptr = &j;
*ptr = 100;
return 0;
}
|
Output
./Solution.c: In function 'main':
./Solution.c:12:9: error: assignment of read-only variable 'ptr'
ptr = &j; /* error */
^
./Solution.c:13:10: error: assignment of read-only location '*ptr'
*ptr = 100; /* error */
^
Advantages of const Qualifiers in C
The const qualifier in C has the following advantages:
- Improved Code Readability: By marking a variable as const, you indicate to other programmers that its value should not be changed, making your code easier to understand and maintain.
- Enhanced Type Safety: By using const, you can ensure that values are not accidentally modified, reducing the chance of bugs and errors in your code.
- Improved Optimization: Compilers can optimize const variables more effectively, as they know that their values will not change during program execution. This can result in faster and more efficient code.
- Better Memory Usage: By declaring variables as const, you can often avoid having to make a copy of their values, which can reduce memory usage and improve performance.
- Improved Compatibility: By declaring variables as const, you can make your code more compatible with other libraries and APIs that use const variables.
- Improved Reliability: By using const, you can make your code more reliable, as you can ensure that values are not modified unexpectedly, reducing the risk of bugs and errors in your code.
Summary
Type |
Declaration |
Pointer Value Change (*ptr = 100) |
Pointing Value Change (ptr = &a) |
Pointer to Variable |
int * ptr |
Yes |
Yes |
Pointer to Constant |
const int * ptr int const * ptr |
No |
Yes |
Constant Pointer to Variable |
int * const ptr |
Yes |
No |
Constant Pointer to Constant |
const int * const ptr |
No |
No |
This article is compiled by “Narendra Kangralkar“. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.