The const qualifier
The keyword const doesn't turn a variable into a constant! The const qualifier really means "read-only"; an object so qualified is a run-time object which cannot (normally) be assigned to. The value of a const-qualified object is therefore not a constant expression in the full sense of the term, and cannot be used for array dimensions, case labels, and the like. (C is unlike C++ in this regard.) When you need a true compile-time constant, use a preprocessor #define (or perhaps an enum).
It is pretty much useful only for qualifying a pointer parameter, to indicate that this function will not change the data that argument points to, but other functions may.
#include <stdio.h> void printcharacters(const char *sptr); int main() { char string[] = "This is a string"; printf("The string is:\n"); printcharacters(string); printf("\n"; return 0; } void printcharacters(const char *sptr) { for (; *sptr != '\0'; sptr++) { printf("%c", sptr); } }
Variables or function parameters that are intended for read-only can be declared with a const qualifier to prevent them from being modified accidentally. If the program tries to modify a const object, it will be detected as an error at compile-time.
For static constants, like string in char *word = "Hello"; and printf("%s%d\,",..); etc. the C compiler usually puts them in a read-only data section. The keyword const
is termed a qualifier because it qualifies the meaning of a declaration.
The general for for creating a constant is as follows
const type name = value;
const double pi = 3.141592654;
Not that you initialize a const in the declaration. The following sequnce isn't correct
const double pi; /* value of pi undefined at this point */ pi = 3.141592654; /* too late! */
If you don't provide a value when you declare the constant, it ends up with an unspecified value that you cannot modify.
If you subsequently wrote a like like this in your program
pi = pi / 2;
the compiler would give you a warning message similar to this:
test.c:6 warning: assignment of read-only variable 'pi'
A const object is not a literal constant but it is still a variable; This is important to take into account when declaring an array; In C89/90, VLA (Variable Lenght Arrays) are not allowed, i.e. the array size must be a compile time constant, meaning that it is either a number or a macro like so: #define SIZE 5;. Thus with the following
#define SIZE 5 int arr[SIZE];
is equivalent to this statement:
int arr[5];
however in C89, you can't declare an array's elements with a symbolic constant created with the const keyword:
const int size = 5; int arr[size]; /* Wrong */
size
must be an integer literal or a constant. It cannot be a variable! Compiled with gcc test.c -std=c89 -Wpedantic -o test, (or with option -Wla warning about variable length arrays being used), yields
warning: ISO C90 forbids variable length array ‘arr’ [-Wvla]
the last example shows how size
is still a variable even when the const
qualifier is applied.
const qualifier and pointers
const char *ptr
This is a pointer to a constant character. It's not possible to change the value pointed by ptr, but the pointer itself can change location it points to. So “const char *” is a (non-const) pointer to a const char.
#include<stdio.h> int main() { char a ='A', b ='B'; const char *ptr = &a; printf( "value pointed to by ptr: %c\n", *ptr); ptr = &b; printf( "value pointed to by ptr: %c\n", *ptr); }
Output:
value pointed to by ptr:A value pointed to by ptr:B
NOTE: There is no difference between const char *ptr
and char const *ptr
as both are pointer to a const char and position of ‘*'(asterik) is also same.
char *const ptr
This is a constant pointer to non-constant character. You cannot change the pointer ptr, but can change the value pointed by ptr.
#include<stdio.h> int main() { char a ='A', b ='B'; char *const ptr = &a; printf( "Value pointed to by ptr: %c\n", *ptr); printf( "Address ptr is pointing to: %d\n\n", ptr); *ptr = b; printf( "Value pointed to by ptr: %c\n", *ptr); printf( "Address ptr is pointing to: %d\n", ptr); }
Output:
Value pointed to by ptr: A Address ptr is pointing to: -1543161763 Value pointed to by ptr: B Address ptr is pointing to: -1543161763
NOTE: Pointer always points to same address, only the value at the location is changed.
const char * const ptr
This is a constant pointer to constant character. You can neither change the value pointed by ptr nor the pointer ptr.
#include<stdio.h> int main() { char a ='A', b ='B'; const char *const ptr = &a; printf( "Value pointed to by ptr: %c\n", *ptr); printf( "Address ptr is pointing to: %d\n\n", ptr); }
Output:
Value pointed to by ptr: A Address ptr is pointing to: -255095482
NOTE: char const * const ptr
is same as const char *const ptr
.
Let's see some other examples
example 1
#include <stdio.h> main() { char A = 'A'; char B = 'B'; char * const ptr1 = &A; ptr1 = &B; /* line number 6: address being re-assigned*/ printf("%c%c",*ptr1); }
ptr1
is declared as a constant pointer to a character, that is it cannot be made to point elsewhere. The line number 6 tries to shift this pointer to point 'B' character, generating an error. You will get the same syntax error for the following code, where the code tries to assing the same address twice:
#include <stdio.h> main() { char A = 'A'; char B = 'B'; char * const ptr1 = &A; ptr1 = &A; /* same address being re-assigned*/ printf("%c%c",*ptr1,); }
Although the address pointed by ptr1
is not being changed here, the compiler does not know what value (same or new) you are trying to assign to a constant pointer. It only knows that whenever the constant pointer appears on the left side of an assignment operator, it has to report the error.
example 2
#include <stdio.h> main() { char A = 'A'; char B = 'B'; char C = 'C'; char D = 'D'; const char *ptr1 = &A;, *const ptr2 = &B; /*line number 5 */ ptr1 = &C; *ptr2 = D; /* This is an error */ printf("%c%c",*ptr1,*ptr2); }
There is no syntax error in line number 6, but in line number 7 only. The use of keyword const
with an object makes that object read-only. So here ptr1 and ptr2 are declared as pointers to constant characters. It means that values pointed by these pointers cannot be changed. However, the pointer itself can be made to point somewhere else. So there's no error in line 6 when we try to change the pointer ptr1 to point somewhere else. The next line when we try to change the value pointed by ptr2, it is not allowed and thus generates the compilation error.