Объединения и перечислимые типы в языке С
Задание 1
- В программе переставьте очередность полей объединения. Проанализируйте результат выполнения измененной программы.
- Определите размерность объединения с помощью оператора sizeof().
- Введите свою фамилию, средний балл за последнюю сессию, начальную букву своего имени и год своего рождения.
- Вместо операции "стрелка" примените операцию "точка".
- С помощью оператора typedef создайте переменную объединения с именем compX, где Х – номер компьютера, за которым выполняется лабораторная работа.
Пример 2. Напишите программу, в которой информация о геометрических фигурах представляется на основе комбинированного использования переменных типа структуры и объединения. В качестве фигур примите эллипс с заданными полуосями, окружность с заданным радиусом и координатами центра, равнобочную трапецию с заданными основаниями и боковыми сторонами. Общие компоненты фигур: площадь фигур, периметр трапеции, длина окружности, длина эллипса.
Программный код решения примера:
#include <stdio.h> #include <conio.h> // #define ?_USE_MATH_DEFINES #include <math.h> const double pi = 3.14159265358979L; int main (void) { double Ltr, AK; struct figure { double area, perimeter; int type; union select { double R[3]; // circle double E[2]; // ellipse double Trap[3]; //trapezium } geom_fig; } geom, *PTR = &geom; printf("\n Figures: 1 - Circle, 2 - Ellipse, 3 - trapezium"); printf("\n\n Select figure: "); scanf_s("%d", &(PTR->type)); switch (PTR->type) { case 1: PTR->geom_fig.R[0] = 5.0L; // радиус круга PTR->geom_fig.R[1] = 1.5L; // x0 PTR->geom_fig.R[2] = 2.5L; // y0 PTR->area = pi*(PTR->geom_fig.R[0])*(PTR->geom_fig.R[0]); PTR->perimeter = 2*pi*(PTR->geom_fig.R[0]); printf("\n %d) Circle:\n R = %1.4f, \ x0 = %1.4f, y0 = %1.4f, area = %1.4f, L = %1.4f\n", \ PTR->type, PTR->geom_fig.R[0], PTR->geom_fig.R[1], PTR->geom_fig.R[2], \ PTR->area, PTR->perimeter); break; case 2: PTR->geom_fig.E[0] = 5.0L; // a - большая полуось PTR->geom_fig.E[1] = 4.0L; // b - малая полуось PTR->area = pi*(PTR->geom_fig.E[0])*(PTR->geom_fig.E[1]); PTR->perimeter = 2.0*pi*(PTR->geom_fig.E[0])*\ (PTR->geom_fig.E[0] - PTR->geom_fig.E[1])/(PTR->geom_fig.E[0]); printf("\n %d) - Ellipse:\n a = %1.4f, b = %1.4f, \ area = %1.4f, L = %1.4f\n", \ PTR->type, PTR->geom_fig.E[0], PTR->geom_fig.E[1], \ PTR->area,PTR->perimeter); break; case 3: PTR->geom_fig.Trap[0] = 12.0L;// AD PTR->geom_fig.Trap[1] = 7.0L; // BD PTR->geom_fig.Trap[2] = 5.5L; // h AK = (PTR->geom_fig.Trap[0] - PTR->geom_fig.Trap[1])/2.0; Ltr = (PTR->geom_fig.Trap[0] + PTR->geom_fig.Trap[1]) + \ 2.0*sqrt(AK*AK + (PTR->geom_fig.Trap[2])*(PTR->geom_fig.Trap[2]) ); PTR->area = 0.5*(PTR->geom_fig.Trap[0] + PTR->geom_fig.Trap[1])*\ (PTR->geom_fig.Trap[2]); PTR->perimeter = Ltr; printf("\n %d) Trapezium:\n AD = %.4f, BC = %.4f, h = %.4f, \ Area = %1.4f, L = %1.4f\n", \ PTR->type, PTR->geom_fig.Trap[0], PTR->geom_fig.Trap[1], \ PTR->geom_fig.Trap[2], PTR->area, PTR->perimeter); break; default : printf("\n\t Error! Break\n"); break; } printf("\n Press any key: "); _getch(); return 0; }
В программе одним из полей структуры geom является объединение. В зависимости от выбора типа – метки активного элемента type – происходит вывод на консоль параметров фигуры, ее площади и длины граничной линии (периметр трапеции и т.д.). Компонент type используется для указания, какой из компонентов (полей) объединения geom_fig является активным в данный момент. Подобную структуру называют переменной структурой.
Определение числа (M_PI) может быть выполнено с помощью препроцессорного определения #define_USE_MATH_DEFINES и подключения математической библиотеки #include<math.h>. В программе это определение числа закомментировано. Используется прямое определение числа с помощью типа const double.
Результат выполнения программы показан на рис. 14.2.