|
Программирование >> Структурное программирование
Другой популярный пример перечислимого типа: enum Months {JAN = 1, FEB, MAR, APR, MAY, YUN, JUL, AUG, SEP, OCT, NOV, DEC}; Это объявление создает определенный пользователем тип Months с константами перечисления, представляющими месяцы года. Поскольку первое значение приведенного перечисления установлено равным 1, оставшиеся значения увеличиваются на 1 от 1 до 12. В объявлении перечислимого типа любой константе перечисления можно присвоить целое значение. Типичная ошибка программирования 3.14 После того, как константа перечисления определена, попытка присвоить ей другое значение является синтаксической ошибкой. Хороший стиль программирования 3.9 Используйте в именах констант перечисления только заглавные буквы. Это выделяет константы в тексте программы и напоминает программисту о том, что константы перечисления не являются переменными. Хороший стиль программирования 3.10 Использование перечислений вместо целых констант облегчает чтение программы. После первого бросания, если игра выиграна, структура while пропускается, поскольку gameStatus не равна CONTINUE. Программа передает управление в структуру if/else, которая печатает Игрок выиграл , если gameStatus равна WON, и Игрок проиграл , если gameStatus равна LOST. После первого бросания, если игра не окончена, sum сохраняется в myPoint. Управление передается структуре while, потому что gameStatus равна CONTINUE. При каждом выполнении while вызывается rollDice для вычисления нового значения переменной sum. Если sum совпадает с myPoint, gameStatus устанавливается равной WON, проверка while терпит неудачу, структура if/else печатает Игрок выиграл и выполнение завершается. Если sum равна 7, gameStatus устанавливается в LOST, проверка while терпит неудачу, структура if/else печатает Игрок проиграл и выполнение завершается. Обратите внимание на интересные применения различных механизмов управления вычислениями, которые мы обсудили. Программа крепе использует две функции - main и rollDice, структуры switch, while, if/else и вложенную структуру if. В упражнениях мы исследуем различные интересные характеристики игры крепе. 3.10. Классы памяти в главах с 1 по 3 мы использовали идентификаторы для имен переменных. Атрибутами переменных являются имя, тип, размер и значение. В этой главе мы используем также идентификаторы в качестве имен функций, определенных пользователем. В действительности каждый идентификатор в программе имеет другие атрибуты, включающие класс памяти , область действия и компоновка. В С++ имеется четыре спецификации класса памяти : auto, register, extern и static. Спецификация класса памяти идентификатора помогает определить его класс памяти, область действия и пространство имен. Класс памяти идентификатора определяет его время жизни - период, в течение которого этот идентификатор существует в памяти. Одни идентификаторы существуют недолго, другие - неоднократно создаются и уничтожаются, третьи - существуют на протяжении всего времени выполнения программы. Областью действия (областью видимости) идентификатора называется область программы, в которой на данный идентификатор можно сослаться. На некоторые идентификаторы можно сослаться в любом месте программы, тогда как на другие - только в определенных частях программы. Компоновка идентификатора определяет для программ с многими исходными файлами (эту тему мы начнем изучать в главе 6), известен ли идентификатор только в одном текущем исходном файле или же в любом исходном файле с соответствующим объявлением. В этом разделе обсуждаются четыре спецификации класса памяти и два класса памяти. В разделе 3.11 обсуждается область действия идентификаторов. Спецификации класса памяти могут быть разбиты на два класса: автоматический класс памяти с локальным временем жизни и статический класс памяти с глобальным временем жизни. Ключевые слова auto и register используются для объявления переменных с локальным временем жизни. Такие переменные создаются при входе в блок, в котором они объявлены, они существуют лишь во время активности блока и исчезают при выходе из блока. К классу с локальным временем жизни могут относиться только переменные. К этому классу относятся локальные переменные функций и параметры функций. Спецификация auto явно объявляет переменные автоматического класса памяти, т.е. с локальным временем жизни. Например, следующее объявление указывает, что переменные х и у типа float являются переменными с локальным временем жизни, т.е. они существуют только в теле функции, в которой появляется объявление: auto float X, у; Локальные переменные являются переменными с локальным временем жизни по умолчанию, так что ключевое слово auto используется редко. Далее мы будем ссылаться на переменные автоматического класса памяти просто как на автоматические переменные. Совет по повышению эффективности 3.1 Автоматический класс памяти - это средство экономии памяти, так как переменные этого класса создаются при входе в блок, в котором они объявлены, и уничтожаются при выходе из блока. Замечание по технике программирования 3.11 Автоматическое хранение - еще один пример принципа наименьших привилегий. Зачем хранить в памяти и делать доступными переменные, когда они не нужны? Обычно данные в версии программы на машинном языке, загружаются для расчетов и другой обработки в регистры. Совет по повышению эффективности 3.2 Спецификация класса памяти register может быть помещена перед объявлением автоматической переменной, чтобы компилятор сохранял переменную не в памяти, а в одном из высокоскоростных аппаратных регистров компьютера. Если интенсивно используемые переменные, такие как счетчики или суммы могут сохраняться в аппаратных регистрах, накладные расходы на повторную загрузку переменных из памяти в регистр и обратную загрузку результата в память могут быть исключены. Типичная ошибка программирования 3.15 Использование нескольких спецификаций класса памяти для одного идентификатора. Для идентификатора может быть указана только одна спецификация класса памяти. Например, если вы указали register, нельзя указать также и auto. Компилятор может проигнорировать объявления register. Например, может оказаться недостаточным количество регистров, доступных компилятору для использования. Приведенное ниже объявление определяет, что целая переменная counter должна быть помещена в один из регистров компьютера; независимо от того, сделает это компилятор или нет, counter получит начальное значение 1: register int counter = 1; Ключевое слово register может применяться только к локальным переменным и параметрам функций. Совет по повышению эффективности 3.3 Часто объявления register не являются необходимыми. Современные оптимизирующие компиляторы способны распознавать часто используемые переменные и решать, помещать их в регистры или нет, не требуя от программиста объявления register. Ключевые слова extern и static используются, чтобы объявить идентификаторы переменных и функций как идентификаторы статического класса памяти с глобальным временем жизни. Такие переменные существуют с момента начала выполнения программы. Для таких переменных память выделяется и инициализируется сразу после начала выполнения программы. Имена функций тоже существуют с самого начала выполнения программы. Однако это не означает, что эти идентификаторы могут быть использованы по всей программе. Как будет видно из раздела 3.11, класс памяти и область действия (где можно использовать имя) - это разные вещи. Существует два типа идентификаторов статического класса памяти: внешние идентификаторы (такие, как глобальные переменные и имена функций), и локальные переменные, объявленные спецификацией класса памяти static. Глобальные переменные и имена функций по умолчанию относятся к классу памяти extern. Глобальные переменные создаются путем размещения их объявлений вне описания какой-либо функции. Глобальные переменные сохраняют свои значения в течение всего времени выполнения программы. На глобальные переменные и функции может ссылаться любая функция, которая расположена после их объявления или описания в файле.
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |