Давно уже собирался и вот решил сделать небольшую шпаргалку по основным спецификаторам, к помощи которых можно и нужно прибегать при программировании. Без лишних слов, сразу же, переходим к сути.
Квалификатор типа const.
Все переменные, определенные с использованием этого ключевого слова не могут изменить своего значения во время выполнения программы. На то они и константы. Чаще всего спецификатор const используется так: когда в программе много раз используется одно и то же числовое значение, создается переменная, имеющая определенное имя, значение которой равно этому числовому значению. Так как переменная не меняется при выполнении программы, используется ключевое слово const. И теперь вместо использования числового значения можно использовать имя константы, что заметно облегчает понимание написанного кода и последующую работу с ним. Поэтому настоятельно рекомендуется в качестве имен переменных использовать что-либо осмысленное, а не просто первый пришедший на ум набор букв. Например, нужно объявить константу, которая будет хранить значение максимального количества принятых байт. Тогда:
// Удачное имя переменной const int maxNumOfBytes = 64; // Неудачное имя переменной const int var123 = 64;
В принципе это основное применение спецификатора const, поэтому, думаю, нет смысла углубляться, так что идем дальше.
Квалификатор типа volatile.
Этот замечательный спецификатор позволяет нам использовать переменную, значение которой может изменяться неявно в процессе выполнения программы. Что же это значит? А вот пример:
bool test = FALSE; if (test) { .... }
Так как наша переменная test нигде явно не изменяется (то есть не стоит слева от оператора присваивания) то заботливый компилятор в результате оптимизации прочитает ее значение только один раз и больше не станет, переменная то на его взгляд нигде не изменяется! А эта переменная на самом деле может принять другое значение в результате выполнения другого потока, либо изменить свое значение неявно в прерывании. А это уже катастрофа... И для того, чтобы ее предотвратить как раз и используется спецификатор volatile. То есть объявить нашу переменную мы должны так:
volatile bool test = FALSE;
Продолжаем...
Спецификатор класса памяти extern.
Если программа состоит из нескольких файлов, как почти всегда и бывает, то без ключевого слова extern не обойтись. Пусть в разных файлах используется одна и та же переменная x. Значит каждый файл должен знать о существовании этой переменной, но просто объявить переменную во всех файлах не прокатит - компилятор этого не допустит. Тут то и придет на помощь спецификатор extern. Вот пример: пусть программа состоит из двух файлов, в каждом из которых есть функции, использующие переменную x:
Файл 1:
unsigned char x; void main() { x = 0x55; ... }
Файл 2:
extern unsigned char x; void testFunction() { x += 0x10; }
При таком объявлении переменной ошибки не будет и все скомпилируется успешно.
Тут есть важный момент - а именно разница между понятиями определить и объявить переменную. При объявлении переменной ей присваивается определенный тип и значение, а при определении - для нее выделяется память. Таким образом, если перед именем переменной стоит спецификатор extern, то мы объявляем переменную, не определяя ее.
Вот собственно и все... Получилась небольшая памятка, которая позволит сразу же и без проблем разобраться с этими ключевыми словами без путаницы.