13. C/C++ Ключевое слово const для переменных

Ключевое слово 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

Постараюсь объяснить логику на картинке

Из-за приведений мы могли бы получить доступ к указателю на указатель на константное значение, после разыменования мы могли бы присвоить адрес константной переменной в указатель на переменную, и далее мы могли бы изменить переменную через ее адрес.

Leave a Reply

Your email address will not be published. Required fields are marked *