Ключевое слово const для переменных
Ключевое слово const для переменных
Ключевое слово const удобно использовать для защиты переменных от изменения (случайного или умышленного) внутри ваших же функций/классов.
Если попытаться обратиться и изменить переменную, защищенную ключевым словом const, то возникнет ошибка (на этапе компиляции).
Переменные с ключевым словом const могут даже находится в защищенной области памяти с доступом «только для чтения», но это зависит от вычислителя и системы (микроконтроллеры/SOC/персональные ПК и тд).
Ключевое слово const используется для декларирования какой-либо константной переменной, для этого оно указывается справа от этой переменной.
Например:
int const Value=10;
Для простых переменных порядок некритичен и можно написать так:
const int Value=10;
Ключевое слово const для указателей:
int * const pValue=&Variable; //создается константный куазатель на НЕКОНСТАНТНОЕ значение
т.е. переменную Variable менять можем, но указатель pValue всегда будет указывать на нее, и его изменить нельзя!!!
Но если указать:
int const * pValue=&Variable;
или const int * pValue=&Variable;
То мы создадим НЕКОНСТАНТНЫЙ указатель на константное значение
т.е. Variable менять НЕ можем, а указатель pValue можем изменить
Для создания константного указателя на константное значение:
int const * const pValue2=&Variable2;
Ключевое слово const для ссылок:
Ссылки являются константными сами по себе, поэтому выражение
int & const Link=Value; //ошибка
является ошибкой, но можно сделать ссылку на константное значение
int const & Link=Value; //правильно
Мнемоническое правило:
Ключевое слово const делает константным (неизменяемым) ПЕРВОЕ выражение/оператор, расположенную слева от него.
Например:
int * const pValue=&Variable;
Слева от ключевого слова находится указатель – и он становится константным, еще левее стоит тип int, но он является 2 выражением, поэтому ключевое слово const на него не распространяется.
Если ключевое слово const расположено левее всех выражений/операторов – это равносильно его «переносу» за ближайшее выражение/оператор
const int * pValue == int const * pValue
Приведение указателей:
Обычно возможно привести указатели и переменные к типу const
type const Name1 = type NO const Name2;
type const * Name1 = type NO const * Name2;
Но есть исключение:
int Value=10;
int *p=&Value;
int const ** p1 = &p; //такое преобразование запрещено
//int const ** p1 = &(int*);
Стандартом разрешены (неявные) преобразования от type* к type const*, но не type ** к type const**
т.е.
int const * p2 = &p; //такое преобразование разрешено
Преобразование type** к type const** запрещено т.к. иначе через него можно было бы получить доступ и изменить константную переменную.
Пример:
int const i = 1;
int * p = 0;
// В этой строке происходит запрещённое преобразование int ** -> int const **
int const ** pp = &p; // теперь *pp указывает на переменную p
// следующая строка скомпилируется, т.к. *pp имеет тип int const*
*pp = &i; // это соответствует p = &i
*p = 2; // изменяем значение переменной i
Постараюсь объяснить логику на картинке
Из-за приведений мы могли бы получить доступ к указателю на указатель на константное значение, после разыменования мы могли бы присвоить адрес константной переменной в указатель на переменную, и далее мы могли бы изменить переменную через ее адрес.

