logo
Харви Дейтел, Пол Дейтел Как программировать на С++ / 02-Deitel-Стр-115-214

200 Глава 3

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

Совет по повышению эффективности 3.2

Спецификация класса памяти register может быть помещена перед объявлением автоматической переменной, чтобы компилятор сохранял переменную не в памяти, а в одном из высокоскоростных аппаратных регистров компьютера. Если интенсивно используемые переменные, такие как счетчики или суммы могут сохраняться в ап­паратных регистрах, накладные расходы на повторную загрузку переменных из памяти в регистр и обратную загрузку результата в память могут быть исключены.

Типичная ошибка программирования 3.15

Использование нескольких спецификаций класса памяти для одного идентификатора. Для идентификатора может быть указана только одна спецификация класса памяти. Например, если вы указали register, нельзя указать также и auto.

Компилятор может проигнорировать объявления register. Например, может оказаться недостаточным количество регистров, доступных компиля­тору для использования. Приведенное ниже объявление определяет, что целая переменная counter должна быть помещена в один из регистров компьютера; независимо от того, сделает это компилятор или нет, counter получит на­чальное значение 1:

register int counter = 1;

Ключевое слово register может применяться только к локальным пере­менным и параметрам функций.

Совет no повышению эффективности 3.3

Часто объявления register не являются необходимыми. Современные оптимизирую­щие компиляторы способны распознавать часто используемые переменные и решать, помещать их в регистры или нет, не требуя от программиста объявления register.

Ключевые слова extern и static используются, чтобы объявить иденти­фикаторы переменных и функций как идентификаторы статического класса памяти с глобальным временем жизни. Такие переменные существуют с мо­мента начала выполнения программы. Для таких переменных память выде­ляется и инициализируется сразу после начала выполнения программы. Имена функций тоже существуют с самого начала выполнения программы. Однако это не означает, что эти идентификаторы могут быть использованы по всей программе. Как будет видно из раздела 3.11, класс памяти и область действия (где можно использовать имя) — это разные вещи.

Существует два типа идентификаторов статического класса памяти: внеш­ние идентификаторы (такие, как глобальные переменные и имена функций), и локальные переменные, объявленные спецификацией класса памяти static. Глобальные переменные и имена функций по умолчанию относятся к классу памяти extern. Глобальные переменные создаются путем размещения их объ­явлений вне описания какой-либо функции. Глобальные переменные сохра­няют свои значения в течение всего времени выполнения программы. На глобальные переменные и функции может ссылаться любая функция, которая расположена после их объявления или описания в файле.

Функции 201

Замечание по технике программирования 3.12

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

Хороший стиль программирования 3.11

Переменные, используемые только в отдельной функции, предпочтительнее объяв­лять как локальные переменные этой функции, а не как глобальные переменные.

Локальные переменные, объявленные с ключевым словом static, известны только в той функции, в которой они определены, но в отличие от автома­тических переменных локальные переменные static сохраняют свои значения в течение всего времени существования функции. При каждом следующем вызове функции локальные переменные содержат те значения, которые они имели при предыдущем вызове. Следующий оператор объявляет локальную переменную count как static и присваивает начальное значение 1

static int count = 1;

Все числовые переменные статического класса памяти принимают нуле­вые начальные значения, если программист явно не указал другие начальные значения. (Статические переменные — указатели, обсуждаемые в главе 5, тоже имеют нулевые начальные значения).

Спецификации класса памяти extern и static имеют специальное значе­ние, когда они применяются явно к внешним идентификаторам. В главе 18, «Другие темы», мы обсудим явное использование extern и static с внешними идентификаторами и программами с множеством исходных файлов.