Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка по С Живицкая (Мет пособие).doc
Скачиваний:
112
Добавлен:
15.06.2014
Размер:
2.11 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;

unsignedhourly: 1;

unsigneddeductions: 3;

};

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

2.3.4.Cмеси.

Смесь (объединение) - это разновидность структуры, позволяющей нескольким переменным различных типов занимать один участок памяти (в разное время). В результате появляется возможность работы в одной и той же области памяти 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 * /

voidmain(void)

{

/* В версии borlond С++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;