Лабораторная работа № 6
Тема: Программирование с использованием перечислений, структур, объединений и полей бит
Цель: Научиться работать с векторными данными языка «С»: структурами и объединениями. Изучить правила объявления структур и объединений, обращение к их полям, построение вложенных векторных типов данных.
Краткая теория
Под перечислением в языке «С» понимают набор мнемонических констант целого типа. Объявление перечисления имеет следующий вид:
enum Имя_Типа {Идент1[=значение1],…, ИдентN[=значениеN]} Имя_переменной;
Пример:
enum WEEK {SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY} day;
В данном примере дням недели будут сопоставлены числа: 0 – воскресенье, 1 – понедельник, …, 6 – суббота.
Для возможности управления сопоставлением идентификаторов и значений необходимо использовать следующее правило: если значение указано явно, то идентификатору присваивается это значение, если значение не указано, то в случае первого идентификатора – ему присваивается значение нуля, в противном случае на единицу большее значение предыдущего элемента.
В программе к переменным такого типа можно обращаться следующим образом:
…
day = FRIDAY;
…
if(day=>TUESDAY) …
…
Сами по себе перечисления никакой функциональной нагрузки не несут. Единственной причиной их использования является их смысловая нагрузка, так как с помощью идентификаторов можно придавать программе читаемость.
Возможно создание нового типа:
typedef enum {…} Имя_типа;
typedef enum {SUNDAY=0, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY} WEEK;
Структура – сложный тип данных, представляющий собой упорядоченное в памяти множество элементов различного типа. Каждый элемент в структуре имеет свое имя и называется полем.
Элементы в структуре располагаются последовательно. Размер структуры определяется суммой размеров всех элементов.
Объявление структуры имеет вид:
struct Имя_типа{поле1; поле2; … полеN;} список_переменных;
Здесь имя типа может быть опущено. В таком случае создание переменных для такой структуры осуществляется только в месте ее объявления.
Объявление поля имеет вид:
тип имя_поля;
Если соседние поля имеют один и тот же тип, то их можно объявлять сразу. Полем может выступать массив, строка, перечисление, другая структура, объединение. Примеры объявлений структур:
struct Point {double x,y;} p1,p2;
struct Circle {double x,y,r; } c1,c2;
struct Student {char name[20]; double rate;} s;
struct Group {char name[20]; struct Student[20]; int num; int kurs;} gr;
При создании переменных структурного типа их можно инициализировать:
struct Имя_типа Имя_переменной = {значение_поля1,…,значение_поля_2};
Пример:
struct Point p = {5.0, 10.0};
struct Circle c = {10.0,10.0,5.0};
struct Student s = {“Вася”,4.5};
struct Group {char name[10]; struct Student st[10]; int num; int kurs;}
gr = {"XX-BC",{{"Alex",4.5},{"Lena",5.0},{"Dima",4.0}},3,2};
При объявлении переменных структурного типа необходимо указывать слово struct каждый раз. Для того чтобы избавиться от этого нужно просто создать тип, используя typedef:
typedef struct {…} Имя_типа;
Имя_типа имя_переменной;
Пример:
typedef struct {char name[20]; double rate;} Student;
struct Group {char name[10]; Student st[10]; int num; int kurs;}
gr = {"XX-BC",{{"Alex",4.5},{"Lena",5.0},{"Dima",4.0}},3,2};
Обращение к полю структуры осуществляется через имя переменной и имя поля, разделенных точкой:
p.x = 15.0; p.y=20.0; printf(“[%lf,%lf]”,p.x,p.y);
c.x = p.x; c.y = p.y; scanf(“%lf”,&c.r);
scanf(“%s %lf”,&s.name,&s.rate);
for(i=0;i<gr.num;i++)
printf(“%s %.2lf\n”,gr.st[i].name, gr.st[i].rate);
Объединение – совокупность элементов различных типов, располагаемых на одном адресном пространстве. Фактически это означает, что все данные располагаются по одному адресу и перекрывают друг друга. Таким образом, изменение одного элемента приводит к изменению остальных элементов объединения. Размер объединения определяется размером самого большого типа данных, входящего в объединение.
Как и в структурах, каждый элемент объединения является полем и может любой тип данных: как простой, так и сложный. Описание объединения и обращение к его элементам имеет тот же синтаксис, что и структуры.
Описание объединения:
union Имя_типа {поле1; …полеN;} имя1, …, имяM;
Примеры:
union MYUNION{double r; unsigned u;} u1;
union MUNION{unsigned char a[2]; unsigned b;} u2;
union TUNION{MYUNION m1; MUNION m2;} u3;
struct STUDENT{char name[20]; double rate; int year;};
union SUNION{struct STUDENT s; unsigned char b[32]; } u4;
В первом примере создается объединение с двумя полями: вещественного и целого типа. Размер объединения равен восьми байтам (размер вещественного поля). Обращение к элементам объединения имеет вид: u1.r и u1.u.
Во втором примере создается объединение с двумя полями, одно из которых является массивом из двух байт, второе – незнаковым целым числом. Размер этого объединения составляет два байта. Обращение к элементам имеет вид: u2.a[i], u2.b, u2.a[0].
В третьем примере объединение состоит из двух объединений. Размер этого составляет 8 байт, в соответствии с максимальным размером элементов. Обращение к полям имеет вид: u3.m1.r, u3.m1.u, u3.m2.a[i], u3.m2.b.
В четвертом примере объединение состоит из структуры и массива незнаковых символов. Размер этого объединения составляет 32 байта. Обращение к элементам имеет вид: u4.b[i], u4.s.name, u4.s.rate, u4.s.year.
В языке «С» возможно организовывать поля бит: целое незнаковое число длиной до 32 бит (до 16 бит в DOS средах), являющееся полем структуры. Описание такой переменной имеет вид:
unsigned имя: разрядность;
Примеры:
struct MStruct{
unsigned a:3;
unsigned b:7;
unsigned c:16;
}
Диапазон значений переменных a, b, c составляет 0..7, 0..127, 0..65535 соответственно.