C programming для начинающих: часть 8 – константы

 

Предыдущая часть

В прошлой части мы рассмотрели использование переменных в коде, для замены данных во время выполнения программы.

Однако иногда может потребоваться задать данные, которые будут неизменными. Для этого в C используются константы (constant).

Возьмём для примера такой код:

#include <stdio.h>

int main (int argc, char **argv) {
    
    printf("My math\n");
    return 0;
}

Предположим – вы хотите использовать число Пи в подсчётах. Т.к. Pi имеет фиксированное занчение – вы можете задать его в константе, после чего оно будет использоваться везде в коде, аналогично переменным – но без изменения данных.

Задать константу вы можете с пощью #define:

#include <stdio.h>

#define PI 3.14

int main (int argc, char **argv) {
    
    printf("My math: %f\n", PI);
    return 0;
}

Как и #include#define является указанием препроцессору, которая будет выполнена до начала компиляции программы.

Обратите  внимание, что в отличии от синтаксиса присваивания данных переменных – для констант не требуется использовать символ равенства “=”. Точку с запятой указывать тоже не требуется.

Запускаем программу:

[simterm]

$ ./constants 
My math: 3.140000

[/simterm]

Константы широко используются в стандратной библиотеке C.

Например – мы можем подключить заголовочный файл math.h, и использовать константы из него:

#include <stdio.h>
#include <math.h>
//#define PI 3.14

int main (int argc, char **argv) {
    
//    printf("My math: %f\n", PI);
    printf("My math: %f\n", M_PI);
    return 0;
}

Запускаем, проверяем:

[simterm]

$ ./constants                                                                                                                                                                               
My math: 3.141593

[/simterm]

Проверим содержимое math.h:

[simterm]

$ cat /usr/include/math.h | grep M_PI
# define M_PI           3.14159265358979323846  /* pi */
# define M_PI_2         1.57079632679489661923  /* pi/2 */
# define M_PI_4         0.78539816339744830962  /* pi/4 */
# define M_PIl          3.141592653589793238462643383279502884L /* pi */
# define M_PI_2l        1.570796326794896619231321691639751442L /* pi/2 */
# define M_PI_4l        0.785398163397448309615660845819875721L /* pi/4 */

[/simterm]

Где и видим константу – # define M_PI           3.14159265358979323846.

Переопределение констант

Как уже говорилось выше – константы предполагают неизменность заданных данных.

Но – давайте изменим наш пример:

#include <stdio.h>
#include <math.h>

#define PI 3.14
#define PI 5.0

int main (int argc, char **argv) {
    
    printf("My math: %f\n", PI);
    printf("My math: %f\n", M_PI);
    return 0;
}

Обратите внимание, что тут мы переопределяем значение константы PI.

Собираем программу:

[simterm]

$ gcc constants.c -o constants
constants.c:5:0: warning: "PI" redefined
 #define PI 5.0
 
constants.c:4:0: note: this is the location of the previous definition
 #define PI 3.14

[/simterm]

Компилятор всегда выдаст предупреждение о том, что константа, заданная с помощью define, была переопределена, т.к. хотя это и допустимо – но преполагается, что константа должна быть действиельно неизменной.

В современном C имеется ещё один способ задать конcтанту – с помощью ключевого слова const.

Создание константы с помощью const схоже с присваиванием значения перменной, например:

...
const int VARNAME = 1000;
..

Изменим программу ещё раз:

#include <stdio.h>
#include <math.h>

#define PI 3.14
#define PI 5.0

const double C_PI = 3.14159265358979323846;

int main (int argc, char **argv) {
    
    printf("My math: %f\n", PI);
    printf("My math: %f\n", M_PI);
    printf("My math: %.10f\n", C_PI);
    return 0;
}

Мы объявили новую константу:

...
const double C_PI = 3.14159265358979323846;
...

И выводим её с помощью printf() и спецификатора %.10f:

...
printf("My math: %.10f\n", C_PI);
...

Проверяем:

[simterm]

$ ./constants 
My math: 5.000000
My math: 3.141593
My math: 3.1415926536

[/simterm]

Если вы попроубете переопеределить константу, заданную с помощью const, как обычную переменную – компилятор сообщит об ошибке и не позволит собрать программу:

...
const double C_PI = 3.14159265358979323846;

int main (int argc, char **argv) {
    
    printf("My math: %f\n", PI);
    printf("My math: %f\n", M_PI);

    C_PI = 100;
    printf("My math: %.10f\n", C_PI);
    return 0;
}
...

Сама ошибка:

[simterm]

$ gcc constants.c -o constants
constants.c:5:0: warning: "PI" redefined
 #define PI 5.0
 
constants.c:4:0: note: this is the location of the previous definition
 #define PI 3.14
 
constants.c: In function ‘main’:
constants.c:14:10: error: assignment of read-only variable ‘C_PI’
     C_PI = 100;
          ^

[/simterm]

assignment of read-only variable ‘C_PI’

Т.е. – помните, что константы, заданные с помощью define – могут быть переопределены (хотя и не должны), а заданные с помощью const – будут неизменными точно.

Продолжение.