Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ТП лекции Раздел 4.doc
Скачиваний:
16
Добавлен:
28.09.2019
Размер:
2.56 Mб
Скачать

Битовые поля

Структура позволяет работать с битовыми полями, то есть существует механизм, позволяющий добраться до каждого бита во внутреннем представлении любого объекта. Полем считается последовательность соседних разрядов в числе типа int или unsigned int, указанных в качестве элементов структуры. Для обозначения того факта, что элементом структуры является битовое поле, служит синтаксис:

<целый тип> [идентификатор] : <размер поля>;

Размер поля указывается в битах. Например, char с: 3; или int: 1;. Выполняемые действия не зависят от выбранного типа, если он из множества {char, int, unsigned, signed}. Тип long недопустим. Идентификатор необязателен, но только он позволяет увидеть поле. Неименованные поля (без идентификатора) просто выравнивают границы меж­ду интересующими нас полями. В Visual C++ битовые поля располагаются от меньших номеров разрядов к большим.

Определение типов

Языки С и C++ позволяют определить новый тип переменных, присвоив сим­вольное имя (идентификатор) какому-то заданному типу. Например:

typedef int SHORT;

typedef char *PTRSTR;

typedef int *STRFUNC();

typedef struct

{

int nCode;

char aValue[30];

} IDENTRY;

SHORT a, b;

PTRSTR name, text;

STRFUNC x, y;

IDENTRY data;

Перечислимые типы

Перечислимый тип может быть определен различными способами. Рассмотрим один из них:

typedef enum

{Aperiodic. Oscillating, Differential. Integral } UnitType:

Вновь введенный тип переменных UnitType перечисляет допустимый диапа­зон изменения любой переменной типа UnitType. Компилятор C++ ассоциирует константу Aperiodic с целой константой 0, константу Oscillating — с 1 и т. д. Например, возможна следующая последовательность операторов:

UnitType unit;

switch (unit)

{

case Aperiodic: transient_a(): break:

case Oscillating: transient_o(); break:

case Differential: transient_d(); break:

case Integral: transientJO; break:

default: puts ("\n Wrong UnitType"):

Элементам перечислений могут быть приписаны другие целые константы. Например:

enum { grave, solemn, frivolous=10, gay } mood;

typedef enum rank { captain=7, major=8, colonel=12 } rang;

Допустимые значения переменной mood будут выбираться из множества {0, 1, 10, 11}.

В последней строке введено сразу два новых типа. Первый (rank) объяв­лен с помощью перечисления enum, другой (rang) — с помощью операции typedef. Идентификатор rank (или rang) определен как описатель типа переменных. Что­бы иметь возможность работать с переменной типа rank, необходимо сначала ее декларировать, например: rank r;. Здесь r — это уже переменная, которой мож­но присвоить одно из перечисленных значений, например: r=major; Теперь, если вывести значение переменной r, вызвав функцию printf("r=%d" ,r);, то мы уви­дим: г=8. В первой строке определена переменная mood перечислимого типа. Ей может быть присвоено любое из перечисленных значений, например mood=gay;. Имя типа перечисления (enumeration tag) здесь не определено. Отметьте, что можно одновременно задать новый тип и переменную этого типа, например:

enum grades { bad=3, good, excellent } g[20], next;

Здесь grades не переменная, а имя типа перечисления (tag). Определяющим моментом здесь является местоположение идентификатора: если он стоит до пере­числений, то с его помощью определяется тип, в противном случае — переменная. Здесь определены массив g[] из 20 элементов перечислимого типа grades и пере­менная next этого же типа. В языке C++ такой способ определения позволяет описать новую переменную типа grades простой декларацией grades gr;. Отметим, что инициализирующее выражение может включать уже декларированные элементы списка перечислений. Поэтому возможно следующее описание перечислимого типа:

enum coins

penny=I, tuppence, nickel=penny+4, dime=10, quarter = nickel*nickel } small change;

Константа 5 будет ассоциирована с элементом nickel, a 25 — с quarter. Обыч­но все константы уникальны, но допустимы и повторения в списке инициализа­торов. Например:

enum coins { penny=l. pence=l. shilling=12};

Перечислимый тип может появляться в любом контексте, в котором вообще употребим какой-либо тип. Например:

enum coins coin; // Переменная coin-типа coins

typedef coins COINS; //Новый тип

COINS *pc: // Указатель па тип COINS

coin = quarter: //Присвоение переменной

int i = penny; // Совместимость с int

pc = new COINS; //Выделение памяти

*pc = coi n; // Присвоение по адресу

penny = dime; // Ошибка, так как penny — константа

Область действия имен для перечислимых переменных подчиняется тем же правилам, что и для стандартных типов. Например:

int dime=49: