C Tutorial
C Const
const means this name will not change. The compiler enforces it, including through pointers.
A name that must stay put
Write const before a type when that name should not be assigned again. The compiler treats a later write as an error. You get the mistake at compile time, not as a wrong answer after the program runs.
Use it for values that are facts in this program: a maximum score, a buffer size, a label you print in several places. If you need to change it, it is not const. Leave the keyword off and use a plain variable.
const int
Initialize a const int on the same line you declare it. There is no later chance to fill it in. After that, you may read it as often as you like.
Example
#include <stdio.h>
int main(void) {
const int max_score = 100;
int score = 88;
printf("%d / %d\n", score, max_score);
return 0;
}max_score = 50; after the declaration does not compile. That is the feature. If the number must change, drop const.
const char *
A string literal is not yours to overwrite. Point at it with const char * so the compiler forbids writes through that pointer. You may still point the pointer at a different string.
Example
#include <stdio.h>
int main(void) {
const char *label = "pass";
printf("%s\n", label);
label = "fail";
printf("%s\n", label);
return 0;
}label[0] = 'P'; would not compile. The characters are const. The pointer itself is not: it moved from "pass" to "fail".
Pointer to const versus const pointer
Read the declaration from right to left, or from the name outward. const next to the type locks the object. const next to the pointer name locks the address.
| Write | What is locked |
|---|---|
const int *p | Cannot change *p. Can point p elsewhere. |
int * const p | Cannot move p. Can change *p. |
const int * const p | Cannot move p and cannot change *p. |
This program uses both of the first two forms. It only performs the assignments that are legal.
Example
#include <stdio.h>
int main(void) {
int n = 5;
int m = 9;
const int *p_to_const = &n;
p_to_const = &m;
printf("read through p_to_const: %d\n", *p_to_const);
int * const const_p = &n;
*const_p = 7;
printf("n after write through const_p: %d\n", n);
return 0;
}Open /c/try and try *p_to_const = 1; or const_p = &m;. gcc rejects both.
What const does not mean
const is not the same as a preprocessor #define. It is a typed name the compiler checks. It is also not a claim that the whole program is frozen: other variables can still change. Only that name (or that object, through that pointer) is locked.
C has no const methods. That is a C++ idea. In C, the pointer forms above are how you promise not to write through an address. Next: static, which changes lifetime and linkage instead of writability.
Worked examples
The short listings above are there so you can see the grammar. The programs here use the same statements on quantities that already have units: a speed, a pH, a count of bases. They are classroom numbers. Air resistance is ignored. g is 9.81 m/s² unless a line says otherwise.
Open them in the C editor at /c/try. Change one measurement and check whether the result still has the right unit.
Physics
Light-travel distance
In vacuum, distance is c t. In 1.5 s, light goes about 4.50×10⁸ m, a bit more than the Earth–Moon distance (which is ~3.84×10⁸ m). const double c is the speed of light in this file, not a loop index.
s = c t
Example
#include <stdio.h>
int main(void) {
const double c = 2.998e8;
double seconds = 1.5;
printf("distance = %.3e m\n", c * seconds);
return 0;
}Maths
Perimeter of a regular hexagon
A regular hexagon has six equal sides. Perimeter is 6 × edge. const int SIDES documents the six and blocks SIDES = 7. For edge 2, P = 12.
P = n × a
Example
#include <stdio.h>
int main(void) {
const int SIDES = 6;
double edge = 2.0;
printf("perimeter = %.1f\n", SIDES * edge);
return 0;
}