diff --git a/Project_1.3/functions.c b/Project_1.3/functions.c index 366a869..a8cacfe 100644 --- a/Project_1.3/functions.c +++ b/Project_1.3/functions.c @@ -94,7 +94,7 @@ void choose_path() // Функция выбора действия после в printf("\nПродолжить поиск корня?\n"); printf("\nC - продолжить, A - закончить работу программы, \ -R - начать поиск на другом отрезке, M - выбрать другой способ решения: \n"); +R - начать поиск на другом отрезке: \n"); do { @@ -146,61 +146,6 @@ R - начать поиск на другом отрезке, M - выбрать } } return; - case 'M': - case 'm': - __fpurge(stdin); - // Включение символа ECHO - term.c_lflag |= ECHO; - - // Применение новых настроек терминала - tcsetattr(0, TCSANOW, &term); - printf("Выберите метод вычисления корня:\ - 0 - метод вилки, 1 - метод хорд, 2 - метод касательных\n(По умолчанию: 0)\n"); - *mth = getchar(); - - printf("Введите новые значения границ a и b: "); - - scanf("%lf%lf", pa, pb); - - if (f(*pa) * f(*pb) > 0) - { - printf("В указанных границах нуля функции не существует.\n"); - printf("Нажмите Ctrl+C и поменяйте границы\n"); - } - if (*pa == *pb) - { - if (f(*pa) == 0) - { - printf("\nКорень уравнения: %lf\n", *pa); - printf("Работа программы завершена.\n"); - exit(0); - } - else - { - printf("Нажмите Ctrl+C и поменяйте границы\n"); - } - } - if (*mth == 0) - { - printf("Fork\n"); - fork_method(); - } - else if (*mth == 1) - { - printf("Chord\n"); - chord_method(); - } - else if (*mth == 2) - { - printf("Newton\n"); - newton_method(); - } - else - { - printf("Fork\n"); - fork_method(); - } - return; default: printf("Ошибка ввода, повторная попытка...\n"); diff --git a/Project_test/out/function_zeros_calculator b/Project_test/out/function_zeros_calculator deleted file mode 100755 index 25ddb11..0000000 Binary files a/Project_test/out/function_zeros_calculator and /dev/null differ diff --git a/Project_test/Makefile b/Test/Makefile similarity index 84% rename from Project_test/Makefile rename to Test/Makefile index 820099b..9c762be 100644 --- a/Project_test/Makefile +++ b/Test/Makefile @@ -6,18 +6,19 @@ CFLAGS= -c -Wall default: build general: main.o functions.o - killall -9 function_zeros_calculator - $(CC) ./out/main.o ./out/functions.o declare.h -o ./out/function_zeros_calculator -lm - + + $(CC) ./out/main.o ./out/functions.o -o ./out/function_zeros_calculator -lm main.o: main.c $(CC) $(CFLAGS) main.c -o ./out/main.o functions.o: functions.c + $(CC) $(CFLAGS) functions.c -o ./out/functions.o clean: rm -rf ./out/main.o ./out/functions.o + build: general clean diff --git a/Project_test/README b/Test/README similarity index 100% rename from Project_test/README rename to Test/README diff --git a/Project_test/declare.h b/Test/declare.h similarity index 92% rename from Project_test/declare.h rename to Test/declare.h index 5096fd8..fbda3e6 100644 --- a/Project_test/declare.h +++ b/Test/declare.h @@ -12,4 +12,5 @@ void fork_method(); void chord_method(); void newton_method(); double numerical_derivative(double x); -void exit_777(); \ No newline at end of file +void exit_777(); +void show_grapgh(); \ No newline at end of file diff --git a/Project_test/functions.c b/Test/functions.c similarity index 55% rename from Project_test/functions.c rename to Test/functions.c index 84a27fe..fa79e56 100644 --- a/Project_test/functions.c +++ b/Test/functions.c @@ -9,7 +9,36 @@ double f(double x) // Функция, заданная пользователем, для которой происходит поиск корней. { - return x * x * x - 125; + return x - 125; +} + +void show_grapgh() +{ + struct termios term; + + tcgetattr(STDIN_FILENO, &term); + term.c_lflag &= ~(ECHO | ICANON); + tcsetattr(STDIN_FILENO, TCSANOW, &term); + + char func[100] = "x - 125"; + // Подключение GNU Plot + FILE *gp = popen("gnuplot -persist", "w"); + + if (gp == NULL) + { + printf("GNUerror\n"); + exit(3); + } + fprintf(gp, "set xrange [-500:500]\n"); + fprintf(gp, "set yrange [0:500]\n"); + fprintf(gp, "plot %s\n", func); + fflush(gp); // очищение буфера вывода + printf("Введите любую букву, чтобы продолжить...\n"); + getchar(); + fprintf(gp, "exit\n"); + term.c_lflag |= (ECHO | ICANON); + tcsetattr(STDIN_FILENO, TCSANOW, &term); + return; } // Приближенное вычисление производной по методу конечных разностей @@ -20,38 +49,34 @@ double numerical_derivative(double x) void newton_method() { - sig_flag = 0; - double left = *pa, right = *pb; - right = left; + *pb = *pa; do { - printf("%lf %lf\n", left, right); - left = right; - right = left - f(left) / numerical_derivative(left); + printf("%lf %lf\n", *pa, *pb); + *pa = *pb; + *pb = *pa - f(*pa) / numerical_derivative(*pa); // Используем численно вычисленную производную - *px = right; + *px = *pb; sleep(1); - } while (fabs(right - left) > eps && f(x) != 0); + } while (fabs(*pb - *pa) > eps && f(x) != 0); return; } void chord_method() { - sig_flag = 0; - double left = *pa, right = *pb; - *px = left; - while ((right - left) > eps && f(x) != 0) + *px = *pa; + while ((*pb - *pa) > eps && f(x) != 0) { // Находим точку пересечения хорды с осью x - *px = (left * f(right) - right * f(left)) / (f(right) - f(left)); - printf("%lf %lf\n", left, right); + *px = (*pa * f(*pb) - *pb * f(*pa)) / (f(*pb) - f(*pa)); + printf("%lf %lf\n", *pa, *pb); // Проверяем знаки функции в точках a и x if (f(*px) == 0) break; - else if (f(*px) * f(left) < 0) - right = *px; + else if (f(*px) * f(*pa) < 0) + *pb = *px; else - left = *px; + *pa = *px; sleep(1); } return; @@ -59,25 +84,24 @@ void chord_method() void fork_method() // Функция поиска корней, использующая метод вилки. { - sig_flag = 0; - double left = *pa, right = *pb; do { - *px = (left + right) / 2; // метод деления отрезка пополам + *px = (*pa + *pb) / 2; // метод деления отрезка пополам // Печать границ для отладки и для отслеживания хода вычислений - printf("%lf %lf\n", left, right); + printf("%lf %lf\n", *pa, *pb); // Проверка, какой из отрезков [a, x] или [x, b] подходит под условие существования корня, // т.е. различие знаков на границе. - if (f(left) * f(x) <= 0) - right = x; - else if (f(right) * f(x) <= 0) - left = x; + + if (f(*pa) * f(x) <= 0) + *pb = x; + else if (f(*pb) * f(x) <= 0) + *pa = x; sleep(1); // Принудительное ожидание программой, для возможности прерывания пользователем. - } while (fabs(right - left) > eps && f(x) != 0); + } while (fabs(*pb - *pa) > eps && f(x) != 0); return; } @@ -85,16 +109,19 @@ void choose_path() // Функция выбора действия после в { sig_flag = 1; - char choice, *ch = &choice; + char choice; - struct termios original_term, modified_term; // Задание структуры, определяющей терминал Linux. + struct termios default_term, modif_term; // Задание структуры, определяющей терминал Linux. - tcgetattr(STDIN_FILENO, &original_term); - modified_term = original_term; - modified_term.c_lflag &= ~(ICANON | ECHO); // отключить канонического режим и отображение ввода - tcsetattr(STDIN_FILENO, TCSANOW, &modified_term); + // Получение текущих настроек терминала + tcgetattr(0, &default_term); + modif_term = default_term; + // Отключение символа ECHO + modif_term.c_lflag &= ~ECHO; + // Применение новых настроек терминала + tcsetattr(0, TCSANOW, &modif_term); - printf("\nПродолжить поиск корня?\n"); + printf("\nПродолжить поиск корня? Напечатайте букву и нажмите Enter\n"); printf("\nC - продолжить, A - закончить работу программы, \ R - начать поиск на другом отрезке: \n"); @@ -102,45 +129,26 @@ R - начать поиск на другом отрезке: \n"); { // Очистка стандартного потока ввода от "лишних" __fpurge(stdin); - *ch = getchar(); // Запись буквы, введенной пользователем в переменную choice. + scanf("%c", &choice); // Запись буквы, введенной пользователем в переменную choice. - switch (*ch) + switch (choice) { case 'C': // Выбор вида "Продолжить вычисление". case 'c': - tcsetattr(STDIN_FILENO, TCSANOW, &original_term); - if (*mth == 0) - { - printf("Fork\n"); - fork_method(); - } - else if (*mth == 1) - { - printf("Chord\n"); - chord_method(); - } - else if (*mth == 2) - { - printf("Newton\n"); - newton_method(); - } - else - { - printf("Fork\n"); - fork_method(); - } + sig_flag = 0; return; // Выход из функции без каких-либо изменений. case 'A': // Выбор вида "Завершить вычисление". case 'a': printf("\nКорень уравнения: %lf\n", *px); printf("Работа программы завершена.\n"); - exit(0); // Принудительное завершение программы с выводом текущего приближения корня. + exit_777(); // Принудительное завершение программы с выводом текущего приближения корня. case 'R': // Выбор вида "Продолжить вычисления с новым отрезком". case 'r': - tcsetattr(STDIN_FILENO, TCSANOW, &original_term); + // Возврат к обычному выводу + tcsetattr(0, TCSANOW, &default_term); printf("Введите новые значения границ a и b: "); @@ -157,22 +165,26 @@ R - начать поиск на другом отрезке: \n"); { printf("\nКорень уравнения: %lf\n", *pa); printf("Работа программы завершена.\n"); - exit(0); + exit_777(); } else { printf("Нажмите Ctrl+C и поменяйте границы\n"); } } + + sig_flag = 0; + __fpurge(stdin); return; default: printf("Ошибка ввода, повторная попытка...\n"); __fpurge(stdin); } - } while (*ch != 'A' || *ch != 'R' || *ch != 'C' || *ch != 'a' || *ch != 'r' || *ch != 'c'); + } while (choice != 'A' || choice != 'R' || choice != 'C' || choice != 'a' || choice != 'r' || choice != 'c' || choice != 'M' || choice != 'm'); - tcsetattr(STDIN_FILENO, TCSANOW, &original_term); + // Применение новых настроек терминала + tcsetattr(0, TCSANOW, &default_term); sig_flag = 0; } @@ -184,4 +196,14 @@ void ctrlc_handler(int signum) // Функция, заменяющая стан printf("\nТекущее приближение: %lf\n", *px); choose_path(); } -} \ No newline at end of file + return; +} + +void exit_777() +{ + struct termios term; + tcgetattr(0, &term); + term.c_lflag |= ~ECHO; + tcsetattr(0, TCSANOW, &term); + exit(1); +} diff --git a/Project_test/main.c b/Test/main.c similarity index 97% rename from Project_test/main.c rename to Test/main.c index 2906229..26a02c6 100644 --- a/Project_test/main.c +++ b/Test/main.c @@ -11,7 +11,6 @@ short method, *mth, sig_flag; int main() { - double tmp; sig_flag = 0; method = 0; @@ -32,7 +31,9 @@ int main() return 1; } - printf("Введите интервал [a, b] и точность eps: "); + show_grapgh(); + + printf("Введите интервал [a, b] и точность eps и нажмите Enter: "); scanf("%lf %lf %lf", pa, pb, &eps); __fpurge(stdin); @@ -65,7 +66,7 @@ int main() { printf("\nКорень уравнения: %lf\n", *pa); printf("Работа программы завершена.\n"); - exit(0); + exit_777(); } else { diff --git a/Test/out/function_zeros_calculator b/Test/out/function_zeros_calculator new file mode 100755 index 0000000..d82de89 Binary files /dev/null and b/Test/out/function_zeros_calculator differ