Г. Шилдт - Полный справочник по C++ (1109478), страница 33
Текст из файла (страница 33)
Битоаыс ноля накладывают нскоторыс ограничения. Напримср, нельзя получить адрсс битового поля. Крома того, бнтовыс поля нельзя организовывать в массивы. Битоаыс поля нельзя объявлять статичсскимн. Нсаозможпо ггрсдугадать, будут ли биты считываться слала направо нли справа налсао при переноса на компьютер другого типа. Все это дсласт программы, использующие битовые поля, машинозааисимыми. Помимо упомянутых, а разных опсрационных системах на битовые поля могут накладыааться дополнитсльныс ограничсния. -~ Объединения Объединение — это область памяти, которая исполшустся для хрансння псрсмснных разных типов.
Обьсдинснис позволяет интсрпрспцюаать один н тот жс набор битов поразному. Объявление объсдщ ~ения напоминаст объявление сгруктурьь Вот сто общин вид. ипаоп имя типа объедшшния ( тиа и ля члена; атпиия чявна; тил и.ия члена; ~ имено экэвллляроя объадиненпя; Например: цпьоп ц суре эп сбал суы ); Это объяалснис нс создаст никаких псрсмснных.
Чтобы объявить экземпляр обьсдинсния, нужно либо указать его имя а конце обьявлсния, либо применить отдельный оператор объявления. Рассмотрим примср программы на языке С, а котором объявляется экземпляр апис объединения ц суре. $ цпаоп и суре апис; Для объявления экземпляра объсдинсния а программе на языка С++ использустся лишь имя его типа, ключсаос слово цпаслг употреблять нс обязательно. Напримср, воз.
как объявляется переменная апис а программа на языке С++. $ ц суре апис; В языкс С++ нс запрещается указывать псрсд этим объяалснисм ключсаос слово ипхоп, по это излишнс, поскольку имя объсдинсния полностью опрсделясг ого тип. В то жс время, а языкс С имя объединения считается дескриптором и поэтому должно сопровождаться ключевым аловом илаоп. (Ситуация аналогична объяалснию структу- Глава 7. Структуры, объединения, перечисления и оператор гурепе1 ры.) Однако, поскольку программы, привело(щые в этом развело, должны быть правильными в обоих языках, мы придерживаемся стиля, принятого в языке С.
В переменной еоче целочисленная переменная х и символьная переменная ец хранятся в олнои и той жс области памяти. Разумсезся, переменная ( занимает 2 баит (если размер типа аое равен 2 банч), а переменная ец — только!. На рис. 7.2 показано, каким образом обе нсремснныс используют одну н ту жс область памяти. В л(обом месте программы на переменную сече можно ссылаться, считая, что в ней хранится либо целое число, либо символ. Рис. 72 Переменные х и ай (гсиользуют оГиединслггс сявге (предполагается, что цеягж число заншяает 2 бинт) При объявлении экземнлара объслинения компилятор автоматически вылелясз.
память, достаточную лля хранения наибольшего члена объединения. Например, если считать, что целые числа запил(ают 2 байт. размер переменной ео»е раасн 2 байт, потому что в ней должна храниться целочисленная переменная 1, хотя псрсмсцная сц занимает только один байт. Для доступа к членам объединения используются тс же синтаксические конструкции, что и лля доступа к членам структуры: онсраторы "." и "->". Для нсгюсрслственного обращения к членам объели~(ения применяется оператор ".".
Если лоступ к экземпляру объединения осушесгвляется через указатель, используется оператор "— г'*. Например, чтобы присвоить элементу э. объслинсння емче число (О, слслует выполнить следующий оператор. $ снос.ъ = 10; В следующем примере функции передастся указатель на нерсмс~п~узо сиге чоьд согс1(овьоп и Туре *но! ( цп-въ = 10; /* присваиваем переменной сгггс эначенне 10, используя функцию Объединения часто используются лля сцсцнального преобразования типов, поскольку к хранящимся в обьелинении данным можно обращаться разными способами. Например, объединение можно исг1ользовагь лля манипуляции безо ами, образующими значение тина ас»ййе, например.
изменять его точность нли выполнять необычныс округления. Чтобы получить представление о полезности обьелинсний при нес(а(щартных преобразованиях типов, допустим, что нам нужно записать в файл значение переменной, имеющей тип иноке 1ое. В языке С/С++ нет функции, прел(ьззцачснной лля записи в файл цеременнои типа ецоке ьое. Разумеется, пользуясь функцией емхъее(>, можно записать в фаил значения любого типа, ~ю лля значений тина яцеке ъое эта функция крайне неэффективна. Однако, используя объединение, можно легко наиисазь функцию роем( ), записываюгцую в файл лвоичнос прслставление значения тина Часть !. Основы языка С++: подмножество С еноте 1пе байт за байтом. (При атом считается, что целое число занимав~ два байта,) Чтобы понять, как это происходит, сначала создадим объединение, состоящее из переменной типа еноте 1пе и двухбайтового символьного массива.
г з опзоп ры еноте зпг з; с)гаг сп(2)г )з Теперь используем объедзиггенне рм в функции раем() . азпс1оде <аедзо.н> опзоп ры ( а)загс 1пс 1з снах с)з[2]г ); 1пе росы(аиотс зпг попг, Р1ЬЕ *гр) 1пе ма1п(чоад) ( Е1ЬЕ гр = череп("ееас.сыр", "ыЬг ) роем(1000, Гр)з /* Загзисываем число 1000 как целое */ гс1оае(ур)з тесотп Оз зпе роем(апогс зпс пои, Р1ье *гр) ппаоп ры ыотдз ыотд.з. = поыг ротс(ыогд.с)г[0), Гр)г /* Запись первой половины "/ тесотп росс(ыотд.с)з[1), гр)з /* Запись второй половины */ Несмотря на то по функция раем() вызывается с целочисленным аргументом, она без проблем вызывает станлартную функцию рпес() для последовательной записи в файл бай~он, из которых состоит целое число.
В языка С++ предусмотрен оссбыи аид объединений, назьгеаемых безымянными (апопгтаиз). Они обсуждамтся аа агпорай часгпи книги. ~ 1 ~Перечисления Перечисление (епцглегабоп) представляет собой набор именованных целочисленных констан~, задающих все допустимые значения переменной данного типа. Перечисления часто встречаются в повседневной жизни. Например, названия монет, имеющих хождение в США, образуют перечисление реппу, п(с)(е), Йгле, г[цапег, )за)Г-()о))аг, г)о))аг Глава 7.
Структуры, объединения, перечислению и оператор (урвбе1 Перечисление определяется как структура и начинается с ключевого слова епшв . Вот как выглялит перечисление: епшя ншп перечисления (список кансгпанпг) список переменных Тип перечисления и списан переменных указывать нс обязательно. (Однако хотя бы один нз этих элементов обьявлсния должен присутствовать.) Слслующий фрагмен~ программы определяет перечисление с именем совп. й епшя созп ( реппу, пфсКе1, с(1я1е, соагсег, )ьа1г бо11вг, бо11аг); Тнп перечисления можно использовать лля объявления переменных.
В языке С оператор, приведенный ниже, объявляет переменную яюпеу типа сохп. й епоп со1п топеуг В языке Се+ переменную мопсу можно объявить с помощью более короткой записи: й согп нпогеуг Кроме гого, в языке С++ имя перечисления залаез. полный тнп. В языке С оно является лсскриптором, и поэтому лля полного объявления необыолимо использовать ключевое слово епшя. (Ситуация аналогична объявлению структур н объединений.) Итак, указанные ниже операторы являются абсолютно правильными.
попсу = бфте; ые(попсу==нвагсег) рг1пей('Это четвертак. 1п")г Главное в перечислении то, что каждая константа обозначает целое число. Следовательно. их можно использовать вместо целочисленных переменных. Значение каждой константы на единицу превышает значение предыдущей. Первая констант равна О. Таким образом, оператор $ рг1пег("Вс %г)", реппу, бйыяе); выводит на экран числа о 3. Значения констант можно задавать с помов(ью инициализатора.
Для этого гюсле имени константы слслуст поставить знак равенства и целое число. Константа, указанная после инциализатора, на свинину превышает значение, присвоенное прелы- душей константе. Например, в следующем фрагменте программы константе ч(спеет присваивается значение 100. епшя соьп ( реппу, п1сКе1, г)1гпе, г(сагеег=100, 'па1г до11аг, с)о11аг); раппу пзске1 61вге сватает Ьа1х со11вт Оо11 Широко распространено заблужлснис, что константы перечисления можно вводить и выводить как строки.
Это нс так. Например, фрагмент программы, приведенный ниже, работает ~(справильно. ( т /* Этот фрагмент работать ие будет. */ пюпеу = бо11аг; рг1гег(*%в", вюпеу); Часть 1. Основы языка Се ы( подмножество С Теперь значения констант распределены так: 0 1 2 100 101 102 Запомните, константа ао11ат — зто просто имя целого числа, а нс строка. Г)о этой жс причине следующий код также неверен.
/* Нвверньй код. вттсру(мопеу, "цхххе"); Иначс говоря, строка, содсржашая имя константы, нс прсобразовывасгся в строковую переменную автоматически. Создать код, выполняюший ввод и вывод имен констан~ псрсчислсния доволыю сложно Это слсдуст дслать лишь тогда, когда вы нс можстс довольствоваться их целыми значсниямн. Например, в программс может возникнуть необходимость вынести на экран назвацис монеты, а нс сс код.
внтасц(мопсу) ( саве реппу: ртхпст("реппу")г Ьх еакн саве пхске1: ртхпст("пхске1"); Ьтввк; савв с)хзав: ртхпсх("г)капе"); Ьтввк; савв с(ваттвт: ртхгтй("х)оаттет")г Ьтеакп саве Ьа1т с)о11ат: ртхпст("Ьа1х с)о11ат"); ЬтеаК) савв оо11ат: ртхпСГ("с)о11ат"); И~югда для этого можно объявить массив строк и использовать константы персчислсния в качество индекса.
Это позволит преобразовать значспис константы в строку, содсржашую сс имя. сват пахпе() (12) =( 'раппу", "пхсКо1", "с)ппе ", "х)цатсет", "Ьа1т оо11ат", "с)о11ах" ); ртхптх("Ъв", вахте(пюпеу)); Разумеется, этот способ можно примснять, только если ни одна из констант перечисления нс была инициализирована, поскольку массив строк индсксирустся с нуля, причем каждый слсдуюший индекс увсличивастся на 1.