Стивен Прата - Язык программирования C. Лекции и упражнения (6-е изд.) 2015
- Название:Язык программирования C. Лекции и упражнения (6-е изд.) 2015
- Автор:
- Жанр:
- Издательство:Вильямс
- Год:0101
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Стивен Прата - Язык программирования C. Лекции и упражнения (6-е изд.) 2015 краткое содержание
Язык программирования C. Лекции и упражнения (6-е изд.) 2015 - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
Структуры и другие формы данных 607
Из-за того, что перечислимый тип является целочисленным, переменные enum могут применяться в выражениях таким же образом, как целочисленные переменные. Они представляют собой удобные метки для операторов case.
В листинге 14.15 приведен краткий пример использования enum. Пример полагается на стандартную схему присваивания значений. В результате константа red получает значение 0, которое делает ее индексом для указателя на строку "red".
Листинг 14.15. Программа enum. с
608 глава 14
Цикл for завершается, когда входная строка совпадает с одной из строк, на которые указывают элементы массива colors. Если цикл находит совпадающий цвет, то значение перечислимой переменной применяется для сопоставления с перечислимой константой, используемой в качестве метки case. Ниже приведены результаты пробного запуска:
Введите цвет (или пустую строку для выхода): blue
Колокольчики синие.
Введите следующий цвет (или пустую строку для выхода): orange
Маки оранжевые.
Введите следующий цвет (или пустую строку для выхода): purple
Цвет purple не известен.
Введите следующий цвет (или пустую строку для выхода):
Программа завершена.
Совместно используемые пространства имен
Термин пространство имен в языке С применяется для идентификации частей программы, в которых распознается то или иное имя. Область видимости входит в состав этой концепции: две переменные, имеющие одно и то же имя, но разные области видимости, не конфликтуют друг с другом, в отличие от двух переменных с одинаковыми именами и одной и той же областью видимости. Существует также аспект категории, относящийся к пространствам имен. Дескрипторы структур, дескрипторы объединений и дескрипторы перечислений в определенной области видимости совместно используют одно и то же пространство имен, и это пространство имен отличается от пространства, применяемого обычными переменными. Это означает, что можно назначить одинаковые имена переменной и дескриптору в рамках одной и той же области видимости без возникновения ошибки, но нельзя объявлять два дескриптора или две переменных с одним и тем же именем в той же самой области видимости. Например, следующие объявления не приводят к конфликту имен в С:
struct rect { double х; double у; }; int rect; // конфликт в С не возникает
Тем не менее, использование одного идентификатора двумя разными пугями может вызвать путаницу, к тому же это не разрешено в C++, т.к. там дескрипторы и переменные помещаются в то же самое пространство имен.
Структуры и другие формы данных 609
Средство typedef: краткое знакомство
Возможность typedef представляет собой усовершенствованное средство манипулирования данными, которое позволяет создавать собственное имя для типа. В этом отношении оно подобно директиве #define, но с гремя отличиями.
• В отличие от #define, средство typedef ограничено назначением символических имен только типам, но не значениям.
• Интерпретация typedef выполняется компилятором, а не препроцессором.
• В рамках своих ограничений средство typedef является более гибким, чем #def ine.
Давайте посмотрим, как работает typedef. Предположим, что вы хотите использовать элемент BYTE для обозначения однобайтовых чисел. Тогда вы просто объявляете BYTE, как если бы это была переменная типа char, и предваряете определение ключевым словом typedef:
typedef unsigned char BYTE;
После этого BYTE можно применять для определения переменных:
BYTE х, у[10] , * z;
Область видимости этого определения зависит от местоположения оператора typedef. Если определение находится внутри функции, область видимости будет локальной в пределах этой функции. Если определение находится вне функции, область видимости будет глобальной.
Для определений typedef часто используются прописные буквы, чтобы напоминать пользователю о том, что имя типа в действительности является символическим сокращением, но разрешены также и строчные буквы:
typedef unsigned char byte;
Имена в typedef подчиняются тем же правилам, которые регламентируют создание допустимых имен переменных.
Хотя создание имени для существующего типа может показаться незначительной возможностью, часто оно будет удобным. В предыдущем примере указание BYTE вместо unsigned char помогает документировать намерение применять переменные BYTE для представления чисел, а не символьных кодов. Использование typedef также способствует лучшей переносимости. Например, ранее мы упоминали о типе size_t, который представляет тип, возвращаемый операцией sizeof, и о типе time t, представляющем тип, который возвращается функцией time(). Стандарт С утверждает, что sizeof и time() возвращают целочисленные типы, но то, какими они должны быть, оставляет на усмотрение реализации. Причина отсутствия конкретики объясняется тем, что в комитете по стандартам С придерживаются мнения, что, скорее всего, не существует единого выбора, который был бы наилучщим для всех компьютерных платформ. Таким образом, было решено создать новое имя типа, подобное time t, и позволить реализациям применять typedef для установки этого имени в какой-то конкретный тип. Тогда появляется возможность предоставить общий прототип, такой как показанный ниже:
time_t time(time_t *);
В одной системе time_t может быть unsigned long, а в другой — unsigned long long. При условии, что включен заголовочный файл time.li, программа может получать доступ к подходящему определению, и в коде можно объявлять переменные типа
time t.
610 Глава 14
Некоторые возможности typedef можно продублировать с помощью #define. Например, указание
#define BYTE unsigned char
заставляет препроцессор заменять BYTE типом unsigned char. Ниже приведен пример typedef, который невозможно воспроизвести посредством #define:
typedef char * STRING;
Без ключевого слова typedef в этом примере сама переменная STRING идентифицировалась бы как указатель на char. Наличие typedef делает STRING идентификатором для указателей на char. Таким образом,
STRING name, sign; означает
char * name, * sign;
Предположим, что вместо этого вы поступили так:
#define STRING char *
Тогда
STRING name, sign; транслируется в
char * name, sign;
В этом случае указателем будет только name.
Средство typedef можно также использовать со структурами:
typedef struct complex { float real; float imag;
} COMPLEX;
Теперь для представления комплексных чисел вместо структуры по имени complex можно применять тип COMPLEX. Одна из целей использования typedef связана с созданием удобных и легко опознаваемых имен для часто встречающихся типов. Например, многие программисты предпочитают применять имя типа STRING или его эквивалент, как в ранее показанном примере. При использовании typedef для именования типа структуры дескриптор можно не указывать:
Читать дальшеИнтервал:
Закладка: