Объединения и перечислимые типы в языке С
Задание 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.
