Структуры и функции языка С
Пример 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