Структуры и функции языка С
Пример 2. Напишите программу выполнения арифметических действий с комплексными числами на основе структурного типа данных и печати результатов выполненных действий с помощью вспомогательной функции.
Для решения данного примера следует указать на действия с комплексными числами, заданными в алгебраической форме [15.4].
Суммой двух комплексных чисел
и
называется число
такое, что справедливы равенства
,
, т.е.

Правило сложения. При сложении комплексных чисел складываются действительные и мнимые части соответственно.
Разностью чисел
и
называется число
такое, что
.
Правило вычитания. При нахождении разности
из действительной и мнимой частей уменьшаемого
вычитаются соответственно действительная и мнимая части вычитаемого:

Произведением двух комплексных чисел
и
называется число
такое, что выполняются равенства:


Правило умножения. Комплексные числа перемножаются как двучлены, при этом учитывается:
.
Частным от деления числа
на
называется число
, такое, что справедливо равенство
.
Правило деления. Чтобы разделить число
на
, следует числитель и знаменатель дроби
умножить на число, сопряженное знаменателю.
Комплексные числа называются сопряженными, если у них равны действительные части, а мнимые противоположны по знаку.
Программный код решения примера:
#include <stdio.h>
#include <conio.h>
#include <locale.h>
// Шаблон структуры
struct comp {
long double Re;
long double Im;
};
// Прототип функции с аргументами:
// структура и симольная переменная
void complex (struct comp ri[2], char op);
int main (void) {
long double x, y;
char op;
// Определение структурной переменной
struct comp ri[2];
setlocale(LC_ALL, ".1251"); // для русских шрифтов
//Для определения чисел с десятичной точкой
setlocale(LC_NUMERIC, "English");
printf("\n\t ДЕЙСТВИЯ С КОМПЛЕКСНЫМИ ЧИСЛАМИ\n");
printf("\n Введите действительную часть 1-го комплексного числа: ");
scanf_s("%lf", &x); _flushall();
ri[0].Re = x;
printf(" Введите мнимую часть 1-го комплексного числа: ");
scanf_s("%lf", &y); _flushall();
ri[0].Im = y;
printf("\n Введите действительную часть 2-го сомплексного числа: ");
scanf_s("%lf", &x); _flushall();
ri[1].Re = x;
printf(" Введите мнимую часть 2-го комплексного числа: ");
scanf_s("%lf", &y); _flushall();
ri[1].Im = y;
printf("\n Введите арифметический оператор: ");
scanf_s("%c", &op); _flushall();
//Вызов функции расчета комплексных чисел
printf("\n Результат действия (\"%c\") над двумя комплексными числами\n (результат с десятичной запятой):", op);
// для русских шрифтов с числами с десятичной запятой
setlocale(LC_ALL, ".1251");
complex (ri, op);
//Для определения числа с десятичной точкой
setlocale(LC_NUMERIC, "English");
//Вызов функции расчета комплексных чисел
printf("\n Результат действия (\"%c\") над двумя комплексными числами\n (результат с десятичной точкой):", op);
complex (ri, op);
printf("\n Нажмите любую клавишу (Press any key): ");
_getch();
return 0;
}
// Вспомогательная функция
void complex (struct comp ri[2], char z) {
// Вспомогательные переменные
double num1, num2, den;
// Выбор арифметического действия
switch (z) {
case '+' :
if ((ri[0].Im + ri[1].Im) >= 0)
printf("\n\t %1.4f + %1.4fi\n", ri[0].Re + ri[1].Re, ri[0].Im + ri[1].Im);
if ((ri[0].Im + ri[1].Im) < 0)
printf("\n\t %1.4f - %1.4fi\n", ri[0].Re + ri[1].Re, -(ri[0].Im + ri[1].Im));
break;
case '-' :
if ((ri[0].Im - ri[1].Im) >= 0)
printf("\n\t %1.4f + %1.4fi\n", ri[0].Re - ri[1].Re, ri[0].Im - ri[1].Im);
if ((ri[0].Im - ri[1].Im) < 0)
printf("\n\t %1.4f - %1.4fi\n", ri[0].Re - ri[1].Re, -(ri[0].Im - ri[1].Im));
break;
case '*' :
if ((ri[0].Re*ri[1].Im + ri[1].Re*ri[0].Im) >= 0)
printf("\n\t %1.4f + %1.4fi\n",\
ri[0].Re * ri[1].Re - ri[0].Im*ri[1].Im, ri[0].Re*ri[1].Im + ri[1].Re*ri[0].Im);
if ((ri[0].Re*ri[1].Im + ri[1].Re*ri[0].Im) < 0)
printf("\n\t %1.4f - %1.4fi\n",\
ri[0].Re * ri[1].Re - ri[0].Im*ri[1].Im, -(ri[0].Re*ri[1].Im + ri[1].Re*ri[0].Im));
break;
case '/' :
if (ri[1].Re != 0 && ri[1].Im != 0) {
den = ri[1].Re*ri[1].Re + ri[1].Im*ri[1].Im;
num1 = (ri[0].Re*ri[1].Re - ri[0].Im*(-ri[1].Im))/den;
num2 = (ri[0].Re*(-ri[1].Im) + ri[1].Re*ri[0].Im)/den;
if (num2 >= 0)
printf("\n\t %1.4f + %1.4fi\n",num1, num2);
if (num2 < 0)
printf("\n\t %1.4f - %1.4fi\n",num1, -num2);
}
else
printf("\n\t Ошибка! Деление на нуль.\n");
break;
default : printf("\n\t Ошибка! Неизвестный оператор.\n");
break;
}
}Возможный результат выполнения программы показан на рис. 15.2.
Задание 2
- Дополните программу вычислением модуля комплексного числа, полученного в результате произведенного арифметического действия.
- Консольный вывод запишите в текстовый файл с именем compX.txt, где Х – номер компьютера, за которым выполняется лабораторная работа.
- Напишите программу ввода комплексных чисел в виде одной строки, например, (4+5.5i) – первое вводимое число как строка, (2–3.3i) – второе вводимое число как строка. Предусмотрите также арифметические действия над комплексными числами.
- Напишите программу возведения комплексного числа в степень (см. формулу бинома Ньютона).
Пример 3. Напишите программу имитатора случайного таймера с помощью указателей на структуру [15.2].
Программный код решения примера:
#include <stdio.h>
#include <conio.h>
#include <time.h>
#include <stdlib.h>
// Глобальный шаблон структуры
struct mtime
{
int hours;
int minutes;
int seconds;
};
// Прототипы вспомогательных функций
void update (struct mtime *t);
void display (struct mtime *t);
// Главная функция
int main (void)
{
int i;
//Создание переменной структурного типа
struct mtime systime;
// Для изменения псевдослучайной последовательности
srand((unsigned) (long)time(NULL));
// Начальная инициализация структурной переменной
systime.hours = 0;
systime.minutes = 0;
systime.seconds = 0;
// Цикл вывода расчетного времени
for (i = 0; i < 10; ++i)
{
update(&systime);
display(&systime);
}
printf("\n\n Press any key: ");
_getch();
return 0;
}
// 1-я вспомогательная функция
void update (struct mtime *t) {
// Заполнение полей структуры случайными числами
t -> hours = (int)(24*rand()/RAND_MAX);
t -> minutes = (int)(60*rand()/RAND_MAX);
t -> seconds = (int)(60*rand()/RAND_MAX);
// Условия расчетного времени
t -> seconds += 1;
if (t -> seconds == 60)
{ t -> seconds = 0; t -> minutes++; }
if (t -> minutes == 60)
{ t -> minutes = 0; t -> hours++; }
if (t -> hours == 24)
t -> hours = 0;
}
// 2-я вспомогательная функция
void display (struct mtime *t) {
printf("\n System time: ");
printf("%02d:", t -> hours);
printf("%02d:", t -> minutes);
printf("%02d\n", t -> seconds);
}В программе аргументами функций update() и display() являются указатели на структуру с дескриптором (этикеткой) mtime. При этом в главной функции main() создается структурная переменная systime по шаблону struct mtime и она передается в функции update() и display() через свой адрес, т.е. &systime. Так происходит 10 раз (в цикле).
Примечание. В прототипе функций указатели на структуру могут быть записаны в обезличенной форме, например:
void update (struct mtime *); void display (struct mtime *);
Возможный результат выполнения программы показан на рис. 15.3

