Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
59
Добавлен:
11.05.2015
Размер:
2.03 Mб
Скачать

2.3.3.Битовые поля.

Битовые поля - это особый тип структуры, определяющий, какую длину имеет каждый член.

Поле - это последовательность соседних двоичных разрядов (бит) внутри одного целого значения. Используются в случаях:

1) Если ограничено место для хранения информации, можно сохранить несколько логических (истинно, ложь) переменных в одном байте.

2) Некоторые интерфейсы устройств передают информацию, закодировав биты в один байт.

3) Некоторым процедурам кодирования необходимо получить доступ к отдельным битам в байте.

Формат:

struct имя структуры {

тип имя 1: длина;

тип имя 2: длина;

тип имя N: длина;

}

Битовые поля должны объявляться, как int, unsigned, signed и могут занимать от 1 до 16 бит. Битовые поля должны объявлять, как unsigned, если имеют длину 1,т.к. 1 бит не может иметь знака.

Пример:

struct prim { int a: 2; unsigned b:3; int 5; int c:1;unsigned d:5; } i, j;

Эта структура обеспечивает размещение (см. рисунок)

Разряды машинного слова

15

14

13

12

11

10

9

8

7

6

5

4

3

2

1

0

d

d

d

d

d

c

Не используется

b

b

b

a

a

Если бы последнее поле было задано так: unsigned d:6, то оно размещалось бы не в первом слове, а в разрядах 0 - 5 второго слова.

Нельзя получить адрес переменной битового поля. Переменные битового поля не могут помещаться в массив. Переходя с компьютера на компьютер нельзя быть уверенным в порядке изменения битов (слева на право или справа налево). Любая программа использует битовые поля и зависит от компьютера. Можно смешивать различные структурные переменные в битовых полях.

Пример:

struct emp {

struct addr address;

float pay;

unsigned lay _ off: 1;

unsigned hourly: 1;

unsigned deductions: 3;

};

Определяет запись служащего, использующего только один байт для хранения информации: статуса служащего; полученной зарплаты и размера удержания. Без использования битовых полей данная информация заняла бы три байта. Обращение к любому полю осуществляется так же, как к элементу записи.

2.3.4.Cмеси.

Смесь (объединение) – это разновидность структуры, позволяющей нескольким переменным различных типов занимать один участок памяти (в разное время). В результате появляется возможность работы в одной и той же области памяти с данными различного вида. Для описания смеси используется ключевое слово union, а соответствующий синтаксис аналогичен синтаксису структуры.

Пусть задано объявление

unionr{intir;floatfr;charcr; }Z;

Здесь ir имеет размер 2 байта

fr имеет 4 байта

cr имеет 1 байт

Для Z будет выделена память достаточная, чтобы сохранять самый большой из 3-х приведенных типов. Т.о. размер Z будет 4 байта. В один и тот же момент времени в z может иметь значение только одно из (ir, fr, cr).

Пример:

# include <stdio.h>

union r { int ir; float fr; char cr; } Z;

float f;

/* объявлена смесь Z типа r. Размер смеси будет определяться размером самого длинного элемента. В данном случае fr * /

void main (void)

{

/* В версии Borland С++3.1 обнаружена ошибка при использовании вычисления и функции вывода вещественных значений элементов структур. Чтобы обойти ошибку, присваиваем вещественное значение элемента union простой вещественной переменной f (f=Z.fr;), а затем используем f в выражениях и наоборот * /

printf ( " размер Z = % d байта \ n", sizeof (z) );

/* sizeof(Z) вычисляет длину переменной Z. Соответственно printf распечатывает вычисленную длину * /

printf ("ввод Z.ir \ n");

scant (" % d", & Z.ir);

printf ("значение ir = % d \n", Z.ir);

printf ("введите Z.fr \ n");

scanf (" % f", & f);

Z.fr = f;

/* Фактически запись в Z.fr (что фактически реализован ввод (scanf (" % f", &Z.ir); )*/

printf (" значение fr = % f \ n"; f);

printf (" введите Z.cr \ n");

flushall ();

/* Очистка буферов ввода - вывода. Такая очистка здесь необходима, т.к. в буфере ввода остается символ конца строки от предыдущего ввода, который затем введется спецификацией %с вместо реально набираемого символа.*/

scanf (" % C", & Z.cr);

printf (" значение cr = % C; \ n", Z.cr);

}

Пример:

размер Z = 4 байта

ввод Z.ir

7 <─┐

значение ir = 7

ввод : Z.fr

8. 3 4 5 6 7 8 <─┐

введите Z.cr

p

значение сr = p;