Ключевое слово const
очень много, оно довольно сложное. Как правило, добавление большого количества const в вашу программу считается хорошей практикой программирования, поищите в Интернете «правильность const», и вы найдете много информации об этом.
Ключевое слово const - это так называемый "квалификатор типа", другие volatile
и restrict
. Как минимум volatile следует тем же (сбивающим с толку) правилам, что и const.
Прежде всего, ключевое слово const служит двум целям. Наиболее очевидным является защита данных (и указателей) от преднамеренного или случайного неправильного использования, делая их доступными только для чтения. Любая попытка изменить переменную const будет обнаружена компилятором во время компиляции.
Но в любой системе, имеющей постоянную память, есть и другая цель, а именно - обеспечить выделение определенной переменной внутри такой памяти - например, EEPROM или флэш-память. Они известны как энергонезависимые воспоминания, NVM. Переменная, размещенная в NVM, будет, конечно, следовать всем правилам переменной const.
Существует несколько различных способов использования ключевого слова const
:
Объявление постоянной переменной.
Это можно сделать как
const int X=1; or
int const X=1;
Эти две формы полностью эквивалентны . Последний стиль считается плохим стилем и не должен использоваться.
Причина, по которой вторая строка считается плохим стилем, возможно потому, что "спецификаторы класса хранения", такие как static и extern, также могут быть объявлены после фактического типа, int static
и т. Д. Но выполнение поэтому для спецификаторов класса хранения комитет C отметил как устаревшую функцию (черновик ISO 9899 N1539, 6.11.5). Следовательно, для согласованности не следует также писать классификаторы типов таким способом. Это не преследует никакой другой цели, кроме как сбить с толку читателя.
Объявление указателя на постоянную переменную.
const int* ptr = &X;
Это означает, что содержимое «X» не может быть изменено. Это нормальный способ объявления указателей подобным образом, в основном как часть параметров функции для «правильности констант». Поскольку 'X' на самом деле не нужно объявлять как const, это может быть любая переменная. Другими словами, вы всегда можете «обновить» переменную до const. Технически, C также позволяет понизить const до простой переменной с помощью явных типов, но это считается плохим программированием, и компиляторы обычно выдают предупреждения против него.
Объявить постоянный указатель
int* const ptr = &X;
Это означает, что сам указатель является константой. Вы можете изменить то, на что он указывает, но вы не можете изменить сам указатель. Это не имеет много применений, есть несколько, например, обеспечение того, чтобы указатель-указатель (указатель-на-указатель) не менял свой адрес при передаче в качестве параметра функции. Вам придется написать что-то не слишком читабельное, например:
void func (int*const* ptrptr)
Я сомневаюсь, что многие программисты на C могут получить const и * прямо там. Я знаю, я не могу - мне пришлось проверить с GCC. Я думаю, именно поэтому вы редко когда-либо видите этот синтаксис для указателя на указатель, даже если это считается хорошей практикой программирования.
Указатели констант также можно использовать для гарантии того, что переменная-указатель сама объявлена в постоянной памяти, например, вы можете объявить какую-то таблицу поиска на основе указателей и выделить ее в NVM.
И, конечно, как указывают другие ответы, константные указатели также могут быть использованы для обеспечения "правильной константности".
Объявить постоянный указатель на постоянные данные
const int* const ptr=&X;
Это два вышеописанных типа указателей, со всеми атрибутами обоих.
Объявление функции-члена только для чтения (C ++)
Поскольку это тег C ++, я должен также упомянуть, что вы можете объявить функции-члены класса как const. Это означает, что функции не разрешается изменять любой другой член класса при вызове, что одновременно предотвращает случайные ошибки программиста класса, но также сообщает вызывающей функции-члену, что они не будут ничего портить позвонив по телефону Синтаксис:
void MyClass::func (void) const;