Читать «Полный справочник по С++» онлайн - страница 20

Герберт Шилдт

void sp_to_dash(const char *str); int main(void)

{

sp_to_dash("строка для проверки"); return 0;

void sp_to_dash(const char *str)

{

while(*str) {

if(*str== ' ’) printf("%c", '-’);

else printf("%c", *str);

str++

}

}

Если бы мы попытались модифицировать строку внутри функции sp_to_dash(), компилятор выдал бы сообщение об ошибке. Например, если написать функцию sp_to_dash() так, как показано ниже, то возникла бы ошибка компиляции.

/* Ошибка */

void sp_to_dash(const char *str)

{

while(*str) {

if(*str==' 1 ) *str = /* Нельзя! Аргумент str

является константным */

printf("%c", *str); str++;

}

}

Многие функции из стандартной библиотеки используют квалификатор const в объявлениях своих параметров. Например, прототип функции strlenO выглядит следующим образом.

| size_t strlen(const char *str);

Объявив указатель str константной, авторы защитили от изменений строку, на которую он ссылается. В принципе, если в стандартной функции нет необходимости модифицировать объект, на который ссылается ее аргумент, то этот аргумент объявляется константным.

Квалификатор const можно также использовать для предотвращения модификации переменных. Помните, что переменную типа const можно модифицировать лишь за пределами программы. Например, ее значение можно изменить с помощью аппаратных устройств. Однако, если переменная объявлена константной, можно гарантировать, что ее изменение может произойти лишь вследствие внешнего вмешательства.

Квалификатор volatile

Квалификатор volatile сообщает компилятору, что значение переменной может изменяться неявно. Например, адрес глобальной переменной можно передать таймеру операционной системы и использовать его для отсчета реального времени. В этом

случае содержимое переменной изменяется без явного выполнения какого-либо оператора присваивания. Это очень важно, поскольку большинство компиляторов языка C/C++ автоматически оптимизируют некоторые выражения, считая, что значения переменных не изменяются, если они не указаны в левой части оператора присваивания. Таким образом, их значения нет смысла перепроверять при каждом обращении. Кроме того, некоторые компиляторы изменяют порядок вычисления выражений в ходе компиляции. Квалификатор volatile предотвращает такие изменения.

Квалификаторы const и volatile можно использовать одновременно. Например, если 0x30 — значение, хранящееся в порте, которое изменяется только под влиянием внешних обстоятельств, то следующее объявление предотвратит непредвиденные побочные эффекты.

| const volatile char *port = (const volatile char *) 0x30;

1J Спецификаторы хранения

B языке С существуют четыре спецификатора хранения.

I extern I static I register

I auto

Эти спецификаторы сообщают компилятору, как хранить объявленную переменную. Общий вид объявления, использующего эти спецификаторы, приведен ниже.

спецификатор хранения тип имяпеременной Обратите внимание на то, что спецификаторы хранения предшествуют всем остальным элементам объявления.