Объединение ( union ) – это тип, который позволяет хранить различные типы данных в одном и том же пространстве памяти (но не одновременно)[14.1].
Объединения образуются во многом подобно структурам. Существуют шаблоны объединений и переменные типа объединения. Они могут быть определены с помощью одного или двух действий, причем в последнем случае используется дескриптор объединения [14.1].
Пример шаблона объединения с дескриптором :
union hold {
int digit;
double bigf;
char letter;
};
Объединение может хранить значение типа int, или double, или char. Структура с такими же полями способна хранить все типы одновременно.
Пример определения трех переменных объединения:
union hold fit; // переменная объединения типа hold union hold save[10];// массив из 10 переменных объединения union hold *ptr; // указатель на переменную типа hold
Первое объявление создает единственную переменную fit. Компилятор выделяет пространство памяти, достаточное для того, чтобы хранить наибольшую из описанных вариантов, а именно тип double, который требует для себя обычно 8 байт. Второе объявление save[10] создает массив с 10 элементами, каждый из которых имеет размер в 8 байт. Третье объявление создает указа-тель, который может содержать адрес объединения .
Рассмотрим варианты инициализации объединения [14.1]:
union hold valA;// создали переменную valA по шаблону union hold
valA.letter = 'R';
union hold valB = valB;// инициализация одного объединения другим
union hold valC = {88};// инициализация числового элемента
Рассмотрим варианты использования объединения:
union hold fit; fit.digit = 23; // Число 23 хранится в переменной fit, 2 байта fit.bigf = 6.78; // Число 23 затерто, хранится 6.78, 8 байтов fit.letter = 'h';// Число 6.78 затерто, хранится символ h,1 байт
Операция точки показывает, какой тип данных используется в текущий момент [14.1]. За один раз запоминается только одно значение. Нельзя одновременно хранить значение типа char и значение типа int, даже если для этого имеется достаточно пространства (памяти для 8 байт). Следить за тем, какие значения на текущий момент хранятся в объединении, входит в обязанности программиста. Бывает, что на различных этапах выполнения программы одни переменные могут быть не нужны, в то время как другие, наоборот, используются только в текущей части программы, поэтому объединения экономят пространство, вместо того чтобы впустую тратить память на не использующиеся в данный момент переменные.
При инициализации полей объединения вместо операции точки можно использовать операцию стрелки, если используется указатель на объединение. В частности, для рассмотренных примеров:
int x; ptr = fit; x = ptr->digit;
В содержимом объединения (в качестве
Фактически объединение является структурой, в которой все элементы имеют нулевое смещение от ее начала. Она имеет достаточную длину, чтобы в нее поместился самый длинный элемент, и при этом выравнивание выполняется правильно для всех типов данных в объединении [14.2]. Над объединениями разрешено выполнять те же операции, что и над структурами: присваивать или копировать как единое целое, брать адрес и обращаться к отдельным элементам.
Объединения могут употребляться в структурах и массивах и наоборот. Способ обращения к члену объединения в структуре (или к члену структуры в объединении) полностью идентичен обращению к элементу вложенной структуры. Объединение можно инициализировать только данными того типа, который имеет его первый элемент [14.2].
Смысловое отличие объединения от структуры состоит в том, что записать информацию в объединение можно с помощью одного из его элементов, а выбрать данные из того участка памяти можно с помощью другого элемента того же объединения [14.3].
К объединениям может быть применен оператор typedef, после чего можно вводить обозначения объединяющих типов, не требующие применения служебного слова union. Рассмотрим пример:
typedef union data
{
char str[79+1];
int a;
double x;
} new_data;
Определения новых переменных (например, student1, student2 ) объединений будут выглядеть таким образом:
new_data student1, student2;
Объединения не относятся ни к скалярным данным, ни к данным агрегирующих типов [14.3].
Объединения не могут сравниваться операциями "==" и "!=" по тем же самым причинам, что и структуры, поскольку элементы объединения не обязательно хранятся в последовательных байтах памяти.
Объединения часто используются для специального преобразования типов, поскольку к хранящимся в объединении данным можно обращаться разными способами [14.4].
Перечислимый (enumerated) и тип служит для объявления символических имен, представляющих целочисленные константы [14.1].
Можно сказать, что enumerated type (перечислимый тип) – это тип данных, заданных списком принадлежащих ему значений.
Назначение
Примеры объявления
enum spectrum {red, orange, yellow, green, blue, violet};
enum spectrum color;
Первое объявление устанавливает как имя дескриптора, который позволяет использовать enum в качестве имени типа. Второе объявление делает color переменной этого типа. Идентификаторы, заключенные в фигурные скобки, перечисляют возможные значения, которые может принимать переменная . Соответственно, возможными значениями color являются red, orange, yellow и т. д. Но эти возможные значения являются целочисленными, т.е. 0, 1, 2, 3, 4, 5. Другими словами, значения в enum начинаются с 0, если не задано иное число, и всегда увеличиваются на 1.
В общем случае перечислимые константы имеют тип int, но перечислимые переменные не так жестко привязаны к целочисленному типу данных, поскольку этот тип может содержать перечислимые константы. Например, перечислимые константы переменной spectrum имеют диапазон 0 ... 5 (как в массиве), поэтому компилятор может выбрать тип unsigned char для представления переменной color.
В языке программирования С к перечислимой переменной можно применять операции инкрементирования "++" и декрементирования "––". Например,
for (color = red; color <= violet; ++color) ...;
По умолчанию константам в перечислимом списке присваиваются целые значения 0, 1, 2 и так далее. В то же время возможны и присваиваемые значения, например:
enum levels {low = 100, medium = 500, high = 2000};
Если назначить конкретное значение одной из констант, то все следующие константы будут пронумерованы последовательно в возрастающем порядке, например:
enum feline {cat, lynx = 10, puma, tiger};
В этом случае cat (кошка) получает значение 0 по умолчанию, lynx (рысь), puma (пума), tiger (тигр), соответственно, получают значения 10, 11, 12.
Перечисления особенно полезны там, где не требуется преобразования значений (целого типа) в имена (
Пример 1. Для переменной типа объединения предусмотрите ввод, и вывод элементов ее полей.
Программный код решения примера:
#include <stdio.h>
#include <conio.h>
#include <string.h>
#define N 79
union hold
{
char str[N+1];
double bigf;
char ch;
int digit;
};
int main (void)
{
double D2;
int i = 0, digit2;
char str2[80], ch2;
union hold fit, *PTR = fit;
//PTR = fit; // вариант взятия адреса
printf("\n\t Fields of the \"union\":\n \
1) string, 2) double, 3) character, 4) integer\n");
do {
printf("\n Enter %d field of the \"union\": ", i+1);
_flushall();
if (i == 0)
{
gets_s(str2, N);
strcpy_s(PTR->str, strlen(str2) + 1, str2);
printf(" The first field: %s\n", PTR->str);
i++; }
else if (i == 1)
{
scanf_s("%lf", D2);
printf(" The second field: %1.4f\n", PTR->bigf = D2);
i++; }
else if (i == 2)
{
scanf_s("%c", ch2);
printf(" The third field: %c\n", PTR->ch = ch2);
i++; }
else
{
scanf_s("%d", digit2);
printf(" The fourth field: %d\n", PTR->digit = digit2);
i++; }
} while (i < 4);
printf("\n 1 field: %s\n 2 field: %1.4f\n \
3 field: %c\n 4 field: %d\n", \
PTR->str, PTR->bigf, PTR->ch, PTR->digit);
printf("\n Press any key: ");
_getch();
return 0;
}
Результат выполнения программы показан на рис 14.1.
(рис 14.1) Результат заполнения полей объединенияКак видно из результата выполнения программы, заполнение четырех полей объединения возможно поочередно. После "прохода" всех полей строчные поля не сохранились.
Задание 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 является активным в данный момент. Подобную структуру называют переменной структурой.
Определение числа $$\pi$$ (M_PI) может быть выполнено с помощью препроцессорного определения #define_USE_MATH_DEFINES и подключения математической библиотеки #include<math.h>. В программе это определение числа $$\pi$$ закомментировано. Используется прямое определение числа $$\pi$$ с помощью типа const double.
Результат выполнения программы показан на рис 14.2.
(рис 14.2) Результат выбора и расчета плоской фигуры Задание 2
Пример 3. Напишите программу вывода на консоль дня недели до и после заданного номера дня недели с помощью enum.
Программный код решения примера:
#include <stdio.h>
#include <conio.h>
const int NUMDAYS = 7;
enum DAYS
{
Mon, // Monday,
Tue, // Tuesday,
Wed, // Wednesday,
Thu, // Thursday,
Fri, // Friday,
Sat, // Saturday,
Sun // Sunday
} day1, day2, day3; // сегодня, вчера, завтра
// Прототипы функций
int day_before(DAYS);
int day_after(DAYS);
void print_day(DAYS);
int main (void) {
printf("\n Days of week:\n 1) Monday, 2) Tuesday, 3) Wednesday, \
4) Thursday,\n 5) Friday, 6) Saturday, 7) Sunday\n");
printf("\n Select the number of days a week: ");
scanf_s("%d", day1);
if (day1 > 7 || day1 < 1)
printf("\n\t Error!\n");
else {
day2 = day_before(day1);
day3 = day_after(day1);
printf("\n If today ");
print_day(day1);
printf("\n yesterday was ");
print_day(day2);
printf("\n and tomorrow will be ");
print_day(day3);
}
printf("\n\n Press any key: ");
_getch();
return 0; }
// Описание функции
int day_after(day) {
int aft, ex;
aft = (day+1) % NUMDAYS; // Остаток от деления по модулю
if (aft == 0)
ex = NUMDAYS;
else
ex = aft;
return ex; }
// Описание функции
int day_before(day) {
int pre, ex;
pre = (day-1) % NUMDAYS;
if (pre == 0)
ex = NUMDAYS;
else
ex = pre;
return ex; }
// Описание функции
void print_day(day) {
int day_i = day-1;
// Массив указателей
static char *days[] =
char *days[] =
{"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
"Sunday" };
printf(" %s\n", days[day_i]); }
В программе использован спецификатор static для массива указателей, инициированных названиями дней недели. В таком случае массив указателей с заданным именем будет не доступен за static внутри функции print_day() инициирует выделение памяти для объекта (массив указателей) и служит определением массива указателей.
Возможный результат выполнения программы показан на рис 14.3.
(рис 14.3) Пример выбора полей перечисления по дням неделиЗадание 3
<locale.h> ).day1, например, day1 = Sun.Пример 4. Напишите программу вывода количества дней для каждого месяца не високосного года на основе
Программный код решения примера:
#include <stdio.h>
#include <conio.h>
int main (void) {
enum month {january = 1, february, march, april, may, june,july, august, september, october, november,
december } aMonth;
int days;
printf("\n Enter the number of the month (1 - 12): ");
scanf_s("%d", aMonth);
switch (aMonth)
{
// 31 день
case january:
case march:
case may:
case july:
case august:
case october:
case december:
days = 31;
break;
// 30 дней
case april:
case june:
case september:
case november:
days = 30;
break;
case february:
days = 28;
break;
default:
printf("\n\t Wrong number of the month\n");
days = 0;
break;
}
if (days)
printf("\n The number of days of the month: %d\n", days);
if (aMonth == february)
printf("\n ... or 29 if it is a leap year\n");
printf("\n\n Press any key: ");
_getch();
return 0;
}
Возможный результат выполнения программы показан на рис 14.4.
(рис 14.4) Подсчет количества дней в месяце годаЗадание 4
Объединение ( union ) – это тип, который позволяет хранить различные типы данных в одном и том же пространстве памяти (но не одновременно)[14.1].
Объединения образуются во многом подобно структурам. Существуют шаблоны объединений и переменные типа объединения. Они могут быть определены с помощью одного или двух действий, причем в последнем случае используется дескриптор объединения [14.1].
Пример шаблона объединения с дескриптором :
union hold {
int digit;
double bigf;
char letter;
};
Объединение может хранить значение типа int, или double, или char. Структура с такими же полями способна хранить все типы одновременно.
Пример определения трех переменных объединения:
union hold fit; // переменная объединения типа hold union hold save[10];// массив из 10 переменных объединения union hold *ptr; // указатель на переменную типа hold
Первое объявление создает единственную переменную fit. Компилятор выделяет пространство памяти, достаточное для того, чтобы хранить наибольшую из описанных вариантов, а именно тип double, который требует для себя обычно 8 байт. Второе объявление save[10] создает массив с 10 элементами, каждый из которых имеет размер в 8 байт. Третье объявление создает указа-тель, который может содержать адрес объединения .
Рассмотрим варианты инициализации объединения [14.1]:
union hold valA;// создали переменную valA по шаблону union hold
valA.letter = 'R';
union hold valB = valB;// инициализация одного объединения другим
union hold valC = {88};// инициализация числового элемента
Рассмотрим варианты использования объединения:
union hold fit; fit.digit = 23; // Число 23 хранится в переменной fit, 2 байта fit.bigf = 6.78; // Число 23 затерто, хранится 6.78, 8 байтов fit.letter = 'h';// Число 6.78 затерто, хранится символ h,1 байт
Операция точки показывает, какой тип данных используется в текущий момент [14.1]. За один раз запоминается только одно значение. Нельзя одновременно хранить значение типа char и значение типа int, даже если для этого имеется достаточно пространства (памяти для 8 байт). Следить за тем, какие значения на текущий момент хранятся в объединении, входит в обязанности программиста. Бывает, что на различных этапах выполнения программы одни переменные могут быть не нужны, в то время как другие, наоборот, используются только в текущей части программы, поэтому объединения экономят пространство, вместо того чтобы впустую тратить память на не использующиеся в данный момент переменные.
При инициализации полей объединения вместо операции точки можно использовать операцию стрелки, если используется указатель на объединение. В частности, для рассмотренных примеров:
int x; ptr = fit; x = ptr->digit;
В содержимом объединения (в качестве
Фактически объединение является структурой, в которой все элементы имеют нулевое смещение от ее начала. Она имеет достаточную длину, чтобы в нее поместился самый длинный элемент, и при этом выравнивание выполняется правильно для всех типов данных в объединении [14.2]. Над объединениями разрешено выполнять те же операции, что и над структурами: присваивать или копировать как единое целое, брать адрес и обращаться к отдельным элементам.
Объединения могут употребляться в структурах и массивах и наоборот. Способ обращения к члену объединения в структуре (или к члену структуры в объединении) полностью идентичен обращению к элементу вложенной структуры. Объединение можно инициализировать только данными того типа, который имеет его первый элемент [14.2].
Смысловое отличие объединения от структуры состоит в том, что записать информацию в объединение можно с помощью одного из его элементов, а выбрать данные из того участка памяти можно с помощью другого элемента того же объединения [14.3].
К объединениям может быть применен оператор typedef, после чего можно вводить обозначения объединяющих типов, не требующие применения служебного слова union. Рассмотрим пример:
typedef union data
{
char str[79+1];
int a;
double x;
} new_data;
Определения новых переменных (например, student1, student2 ) объединений будут выглядеть таким образом:
new_data student1, student2;
Объединения не относятся ни к скалярным данным, ни к данным агрегирующих типов [14.3].
Объединения не могут сравниваться операциями "==" и "!=" по тем же самым причинам, что и структуры, поскольку элементы объединения не обязательно хранятся в последовательных байтах памяти.
Объединения часто используются для специального преобразования типов, поскольку к хранящимся в объединении данным можно обращаться разными способами [14.4].
Перечислимый (enumerated) и тип служит для объявления символических имен, представляющих целочисленные константы [14.1].
Можно сказать, что enumerated type (перечислимый тип) – это тип данных, заданных списком принадлежащих ему значений.
Назначение
Примеры объявления
enum spectrum {red, orange, yellow, green, blue, violet};
enum spectrum color;
Первое объявление устанавливает как имя дескриптора, который позволяет использовать enum в качестве имени типа. Второе объявление делает color переменной этого типа. Идентификаторы, заключенные в фигурные скобки, перечисляют возможные значения, которые может принимать переменная . Соответственно, возможными значениями color являются red, orange, yellow и т. д. Но эти возможные значения являются целочисленными, т.е. 0, 1, 2, 3, 4, 5. Другими словами, значения в enum начинаются с 0, если не задано иное число, и всегда увеличиваются на 1.
В общем случае перечислимые константы имеют тип int, но перечислимые переменные не так жестко привязаны к целочисленному типу данных, поскольку этот тип может содержать перечислимые константы. Например, перечислимые константы переменной spectrum имеют диапазон 0 ... 5 (как в массиве), поэтому компилятор может выбрать тип unsigned char для представления переменной color.
В языке программирования С к перечислимой переменной можно применять операции инкрементирования "++" и декрементирования "––". Например,
for (color = red; color <= violet; ++color) ...;
По умолчанию константам в перечислимом списке присваиваются целые значения 0, 1, 2 и так далее. В то же время возможны и присваиваемые значения, например:
enum levels {low = 100, medium = 500, high = 2000};
Если назначить конкретное значение одной из констант, то все следующие константы будут пронумерованы последовательно в возрастающем порядке, например:
enum feline {cat, lynx = 10, puma, tiger};
В этом случае cat (кошка) получает значение 0 по умолчанию, lynx (рысь), puma (пума), tiger (тигр), соответственно, получают значения 10, 11, 12.
Перечисления особенно полезны там, где не требуется преобразования значений (целого типа) в имена (
Пример 1. Для переменной типа объединения предусмотрите ввод, и вывод элементов ее полей.
Программный код решения примера:
#include <stdio.h>
#include <conio.h>
#include <string.h>
#define N 79
union hold
{
char str[N+1];
double bigf;
char ch;
int digit;
};
int main (void)
{
double D2;
int i = 0, digit2;
char str2[80], ch2;
union hold fit, *PTR = fit;
//PTR = fit; // вариант взятия адреса
printf("\n\t Fields of the \"union\":\n \
1) string, 2) double, 3) character, 4) integer\n");
do {
printf("\n Enter %d field of the \"union\": ", i+1);
_flushall();
if (i == 0)
{
gets_s(str2, N);
strcpy_s(PTR->str, strlen(str2) + 1, str2);
printf(" The first field: %s\n", PTR->str);
i++; }
else if (i == 1)
{
scanf_s("%lf", D2);
printf(" The second field: %1.4f\n", PTR->bigf = D2);
i++; }
else if (i == 2)
{
scanf_s("%c", ch2);
printf(" The third field: %c\n", PTR->ch = ch2);
i++; }
else
{
scanf_s("%d", digit2);
printf(" The fourth field: %d\n", PTR->digit = digit2);
i++; }
} while (i < 4);
printf("\n 1 field: %s\n 2 field: %1.4f\n \
3 field: %c\n 4 field: %d\n", \
PTR->str, PTR->bigf, PTR->ch, PTR->digit);
printf("\n Press any key: ");
_getch();
return 0;
}
Результат выполнения программы показан на рис 14.1.
(рис 14.1) Результат заполнения полей объединенияКак видно из результата выполнения программы, заполнение четырех полей объединения возможно поочередно. После "прохода" всех полей строчные поля не сохранились.
Задание 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 является активным в данный момент. Подобную структуру называют переменной структурой.
Определение числа $$\pi$$ (M_PI) может быть выполнено с помощью препроцессорного определения #define_USE_MATH_DEFINES и подключения математической библиотеки #include<math.h>. В программе это определение числа $$\pi$$ закомментировано. Используется прямое определение числа $$\pi$$ с помощью типа const double.
Результат выполнения программы показан на рис 14.2.
(рис 14.2) Результат выбора и расчета плоской фигурыЗадание 2
Пример 3. Напишите программу вывода на консоль дня недели до и после заданного номера дня недели с помощью enum.
Программный код решения примера:
#include <stdio.h>
#include <conio.h>
const int NUMDAYS = 7;
enum DAYS
{
Mon, // Monday,
Tue, // Tuesday,
Wed, // Wednesday,
Thu, // Thursday,
Fri, // Friday,
Sat, // Saturday,
Sun // Sunday
} day1, day2, day3; // сегодня, вчера, завтра
// Прототипы функций
int day_before(DAYS);
int day_after(DAYS);
void print_day(DAYS);
int main (void) {
printf("\n Days of week:\n 1) Monday, 2) Tuesday, 3) Wednesday, \
4) Thursday,\n 5) Friday, 6) Saturday, 7) Sunday\n");
printf("\n Select the number of days a week: ");
scanf_s("%d", day1);
if (day1 > 7 || day1 < 1)
printf("\n\t Error!\n");
else {
day2 = day_before(day1);
day3 = day_after(day1);
printf("\n If today ");
print_day(day1);
printf("\n yesterday was ");
print_day(day2);
printf("\n and tomorrow will be ");
print_day(day3);
}
printf("\n\n Press any key: ");
_getch();
return 0; }
// Описание функции
int day_after(day) {
int aft, ex;
aft = (day+1) % NUMDAYS; // Остаток от деления по модулю
if (aft == 0)
ex = NUMDAYS;
else
ex = aft;
return ex; }
// Описание функции
int day_before(day) {
int pre, ex;
pre = (day-1) % NUMDAYS;
if (pre == 0)
ex = NUMDAYS;
else
ex = pre;
return ex; }
// Описание функции
void print_day(day) {
int day_i = day-1;
// Массив указателей
static char *days[] =
char *days[] =
{"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
"Sunday" };
printf(" %s\n", days[day_i]); }
В программе использован спецификатор static для массива указателей, инициированных названиями дней недели. В таком случае массив указателей с заданным именем будет не доступен за static внутри функции print_day() инициирует выделение памяти для объекта (массив указателей) и служит определением массива указателей.
Возможный результат выполнения программы показан на рис 14.3.
(рис 14.3) Пример выбора полей перечисления по дням неделиЗадание 3
<locale.h> ).day1, например, day1 = Sun.Пример 4. Напишите программу вывода количества дней для каждого месяца не високосного года на основе
Программный код решения примера:
#include <stdio.h>
#include <conio.h>
int main (void) {
enum month {january = 1, february, march, april, may, june,july, august, september, october, november,
december } aMonth;
int days;
printf("\n Enter the number of the month (1 - 12): ");
scanf_s("%d", aMonth);
switch (aMonth)
{
// 31 день
case january:
case march:
case may:
case july:
case august:
case october:
case december:
days = 31;
break;
// 30 дней
case april:
case june:
case september:
case november:
days = 30;
break;
case february:
days = 28;
break;
default:
printf("\n\t Wrong number of the month\n");
days = 0;
break;
}
if (days)
printf("\n The number of days of the month: %d\n", days);
if (aMonth == february)
printf("\n ... or 29 if it is a leap year\n");
printf("\n\n Press any key: ");
_getch();
return 0;
}
Возможный результат выполнения программы показан на рис 14.4.
(рис 14.4) Подсчет количества дней в месяце годаЗадание 4
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.