Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабы_по_проге_Берлин / Книги / учебное пособие ОАиП.pdf
Скачиваний:
49
Добавлен:
11.02.2015
Размер:
947 Кб
Скачать

void main(void)

{rect pt; int s; do

{clrscr();

puts("введите координаты левого нижнего угла фигуры"); scanf("%d%d",&pt.p1.x,&pt.p1.y);

puts("введите координаты правого верхнего угла фигуры"); scanf("%d%d",&pt.p2.x,&pt.p2.y);

pt=analiz(pt); // анализ и коррекция координат угловых точек

} while(pt.p1.x>pt.p2.x && pt.p1.y>pt.p2.y); s=(pt.p2.x-pt.p1.x)*(pt.p2.y-pt.p1.y); // вычисление площади фигуры

printf("площадь фигуры S= %d",s);

 

getch();

 

 

 

}

 

 

 

rect analiz(rect ptt)

 

 

 

{ void (*f)(int,rect *)={swap};

// указатель на функцию

swap

rect *ptr;

 

 

 

ptr=&ptt;

// ptr содержит адрес стр-ры ptt

 

if (ptt.p1.x>ptt.p2.x) (*f)(1,ptr);

// x1>x2 выполняем в (*f)

x1<->x2

if (ptt.p1.y>ptt.p2.y) (*f)(2,ptr);

// y1>y2 выполняем в (*f)

y1<->y2

return ptt;

 

 

 

}

void swap(int n,rect *ptr) // замена одноименных координат 2 точек

{ int i;

// из функции не требуется возврата т.к.

switch (n)

// замена выполняется по адресу стр-ры ptt

{ case 1 : i=ptr->p1.x; ptr->p1.x=ptr->p2.x; ptr->p2.x=i; break; case 2 : i=ptr->p1.y; ptr->p1.y=ptr->p2.y; ptr->p2.y=i; break;

}

}

Поля бит

Существует несколько разновидностей структур. Одна из них - это поля бит. Поле представляет собой последовательность соседних двоичных разрядов (бит) внутри одного целого значения. Каждое поле может иметь тип unsigned int или signed int и размещается в машинном слове целиком, а вся группа полей может выходить за пределы машинного слова. Поле бит – особый тип структуры определяющий какую длину имеет каждый ее элемент. Общий вид объявления полей бит имеет вид:

struct имя стуктуры { тип имя 1: длина;

. . .

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

};

Наиболее распространенный подход к использованию полей можно

показать на примере объявления следующей структуры: struct pole

{int p1:1; unsigned p2:2; int:6;

int p3:4 } pl;

Объявление такого вида обеспечивает размещение стуктуры (полей бит) в памяти следующим образом. В полях типа signed крайний левый бит является знаковым. Таким образом, поле signed int p:1 может быть использовано для хранения значений -1 и 0, так как любое не нулевое значение поля p будет интерпретироваться как -1. Поле signed int p:2, в отличие от int p:1, может принимать три значения -1,0,1. В объявлении структуры имеется еще два поля (int:6; int ёp3:4). Первое указывает, что структура содержит 6 неиспользуемых бит, второе предназначено для чисел в диапазоне от –7 до 7.

В Borland С самый левый бит является знаковым. Поля могут не иметь имени; с помощью безымянного поля (задаваемого только двоеточием и шириной) организуется пропуск требуемого количества разрядов. Ширина равная нулю, используется тогда когда необходимо выйти на границу следующего слова.

Все особенности, связанные с использованием полей, например: может ли поле байт перейти границу слова, зависят от аппаратной реализации.

При определенном удобстве работа с полями может повлечь некоторые трудности. Они связаны, например, с тем, что на одних машинах поля размещаются слева направо, на других - справа налево. Это в свою очередь влечет некоторые трудности при перенесении программ. Поля не могут быть массивами и не имеют адресов и, следовательно, операция & к ним не применима.

Объединения

Объединение представляет собой структурированную переменную с несколько иным способом размещения элементов в памяти. Если в структуре (как и в массиве) элементы расположены последовательно друг за другом, то в объединении "параллельно". То есть для их размещения выделяется одна общая память, в которой они перекрывают друг друга и имеют в ней общий адрес. Размерность ее определяется максимальной размерностью элемента объединения. Таким образом, при использовании объединений появляется возможность работы с данными различных типов и размеров в одной и той же области памяти. Синтаксис объединения полностью совпадает с синтаксисом структуры, только ключевое слово struct заменяется на union:

Спецификация доступа к элементам объединения, как и у полей бит, полностью соответствует тому, как это осуществляется у обычных структур:

имя_объединения . имя поля объединения; или при работе с указателями:

имя_указателя _на_объединение-> имя_поля_объединения;

Рассмотрим пример объявления и некоторых вариантов использования объединения:

union un_type

{ int i;

// пример объявления

double d;

// шаблона объединения

char c;

 

};

 

un_type un;

// переменная типа объединения

un_type un_mas[6]; // массив из шести элементов

un_type *pt;

// указатель на переменную типа un_type

Первое описание приводит к выделению памяти под одну переменную un. При этом компилятор выделяет достаточно памяти для размещения max из переменных описанных в шаблоне un_type, т.е. 8 байт (тип double). Для массива un_mas[6] выделяется 6х8 байт памяти. Механизм использования объединения может быть рассмотрен на следующем примере:

un.i=14;

// 14 записывается в переменную un; исп-ся 2 байта

un.d=3.4;

// 14 стирается, 3.4 записывается; исп-ся 8 байтов

un.c=‘k’;

// 3,4 стирается, записывается k; используется 1 байт

В каждый момент времени запоминается только одно значение; нельзя записать char и int одновременно в одно объединение даже, если для этого достаточно памяти. Приведенный ниже фрагмент демонстрирует ошибочное использование полей объединения:

un.d=2.4;

 

un.i=14;

 

f=5.2*un.d;

// ошибка

Ошибка заключается в том, что в момент использования un.d его значение 2.4 затерто оператором un.i=14;

Как отмечалось выше, с объединениями можно использовать операцию -> аналогично, как это делалось со структурами.

pt=&un;

 

f=pt->d;

// аналогично f=un.d

Объединение может быть использовано не только для экономии памяти. Если записать в один элемент объединения некоторое значение, то через другой элемент это же значение можно прочитать уже в другой форме представления Таким образом форму представления данных в памяти можно менять совершенно свободно.

Переменные с изменяемой структурой

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

Рассмотрим пример, в котором информация о геометрических фигурах

представляется на основе комбинированного использования структуры и объединения.

struct figure

 

{

double area,perimetr;

// общие компоненты

 

int type;

// признак компонента

 

union

// перечисление компонент

 

{ double radius;

// окружность

 

double a[2];

// прямоугольник

 

double b[3];

// треугольник

 

} geom_fig;

 

}

fig1, fig2;

 

В общем случае каждый объект типа figure будет состоять из трех компонентов: area, perimetr, type. Компонент type называется меткой активного компонента, так как он используется для указания, какой из компонентов объединения geom_fig является активным в данный момент. Такая структура называется переменной структурой, потому что ее компоненты меняются в зависимости от значения метки активного компонента (значение type).

Отметим, что вместо компоненты type типа int, целесообразно было бы использовать перечисляемый тип. Например, такой

enum figure_chess { CIRCLE, BOX, TRIANGLE } ;

Константы CIRCLE, BOX, TRIANGLE получат значения соответственно равные 0, 1, 2. Переменная type может быть объявлена как имеющая перечислимый тип :

enum figure_chess type;

Вэтом случае компилятор СИ предупредит программиста о потенциально ошибочных присвоениях, таких, например, как

figure.type = 40;

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

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

{общие компоненты; метка активного компонента; union

{описание компоненты 1 ; описание компоненты 2 ;

. . .

описание компоненты n ;

} идентификатор-объединения ;

} идентификатор-структуры ;

Пример определения переменной структуры: struct inform