Опубликован: 14.12.2010 | Доступ: свободный | Студентов: 3137 / 738 | Оценка: 4.53 / 4.12 | Длительность: 26:28:00
Лекция 16:

Структуры и функции языка С

< Лекция 15 || Лекция 16: 1234 || Лекция 17 >

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

Для решения данного примера следует указать на действия с комплексными числами, заданными в алгебраической форме [15.4].

Суммой двух комплексных чисел z_1 = x_1 + y_1i и z_2 = x_2 + y_2i называется число z = x + yi такое, что справедливы равенства х=х_1 + х_2, у = у_1 + у_2, т.е.

z = (x_1 + x_2) + (y_1 + y_2)i, где\  i – мнимая\ единица (i=\sqrt-1).

Правило сложения. При сложении комплексных чисел складываются действительные и мнимые части соответственно.

Разностью чисел z_1 и z_2 называется число z такое, что z_1 = z – z_2.

Правило вычитания. При нахождении разности z_1 – z_2 из действительной и мнимой частей уменьшаемого z_1 вычитаются соответственно действительная и мнимая части вычитаемого:

z = (x_1 – x_2) + (y_1 – y_2)i.

Произведением двух комплексных чисел z_1 = x_1 + y_1i и z_2 = x_2 + y_2i называется число z = x + yi такое, что выполняются равенства:

х = х_1х_2 – у_1у_2,у = х_1у_2 + х_2у_1.

Правило умножения. Комплексные числа перемножаются как двучлены, при этом учитывается: i^2 = –1.

Частным от деления числа z_1 на z_2 (z_2 \neq 0) называется число z, такое, что справедливо равенство z\cdot z_2 = z_1.

Правило деления. Чтобы разделить число z_1 на z_2 (z_2 \neq 0), следует числитель и знаменатель дроби z_1/z_2 умножить на число, сопряженное знаменателю.

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

Программный код решения примера:

#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.

Результат действия над двумя комплексными числами

Рис. 15.2. Результат действия над двумя комплексными числами

Задание 2

  1. Дополните программу вычислением модуля комплексного числа, полученного в результате произведенного арифметического действия.
  2. Консольный вывод запишите в текстовый файл с именем compX.txt, где Х – номер компьютера, за которым выполняется лабораторная работа.
  3. Напишите программу ввода комплексных чисел в виде одной строки, например, (4+5.5i) – первое вводимое число как строка, (2–3.3i) – второе вводимое число как строка. Предусмотрите также арифметические действия над комплексными числами.
  4. Напишите программу возведения комплексного числа в степень (см. формулу бинома Ньютона).

Пример 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

Пример вывода полей структуры на консоль

Рис. 15.3. Пример вывода полей структуры на консоль
< Лекция 15 || Лекция 16: 1234 || Лекция 17 >
Мухаммадюсуф Курбонов
Мухаммадюсуф Курбонов