This commit is contained in:
ada-dmitry
2023-12-27 16:23:28 +03:00
parent e405b960a7
commit 133d1abffa
12 changed files with 161 additions and 120 deletions
+6 -12
View File
@@ -1,25 +1,19 @@
# Это комментарий, который говорит, что переменная CC указывает компилятор, используемый для сборки
CC= gcc
#Это еще один комментарий. Он поясняет, что в переменной CFLAGS лежат флаги, которые передаются компилятору
CFLAGS= -c -Wall
CFLAGS= -Wall -pedantic
default: build
general: main.o functions.o
$(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
rm ./out/function_zeros_calculator
build: general clean
build:
$(CC) ./main.c ./functions.c $(CFLAGS) -o ./out/function_zeros_calculator -lm
run:
./out/function_zeros_calculator
./out/function_zeros_calculator
+29 -11
View File
@@ -1,35 +1,53 @@
# Function Zeros Calculator
## Описание
Эта программа предназначена для вычисления нулей функции на языке C в среде Linux.
## Установка
## Установка (с помощью репозитория на GitHub)
1. Склонируйте репозиторий: git clone https://github.com/ada-dmitry/tmp_project.git
2. Перейдите в каталог проекта: cd /Project_1.2
2. Перейдите в директорию проекта: cd /done_project
3. Следуйте указаниям пункта "Использование"
## Установка (с помощью архива .tar)
1. Распакуйте архив в любую удобную вам директорию.
2. С помощью терминала зайдите в распакованную директорию по заданному пути.
3. Следуйте указаниям пункта "Использование"
## Использование
0. Для нормальной работы программы необходимо установить программу GNU PLot
(sudo apt install gnuplot)
0. Для нормальной работы программы необходимо установить программу GNU PLot и сборщик make
(sudo apt install gnuplot || sudo apt install make)
1. Соберите программу: make
2. Запустите программу: ./out/function_zeros_calculator
3. Введите необходимые параметры для вычисления нуля функции: a - ЛЕВАЯ граница отрезка
b - ПРАВАЯ граница отрезка, eps > 0 - точность вычисления корня(до 10^-6).
2. Запустите программу: make run
3. Строго следуйте указаниям программы, вводя границы отрезка, точность вычисления корня и
выбирая метод вычисления.
## Замечания
1. Для корректной работы программы, необходимо вводить отрезок, на котором есть лишь один корень
(это можно проверить благодаря графику).
(это можно проверить благодаря графику).
2. После вызова меню выбора действий (Ctrl+C) можно использовать как верхний регистр, так и нижний.
3. Не рекомендуется бесконечно вызывать Ctrl+C без выбора действия, это может повлечь ошибки
вследствие переполнения памяти.
вследствие переполнения памяти.
## Обработка сигнала SIGINT
Программа обрабатывает сигнал SIGINT, что позволяет давать пользователю выбор действия
при нажатии сочетания клавиш Ctrl+C.
## Обработка сигнала SIGTSTP
Программа обрабатывает сигнал SIGTSTP, переводящий программу в фоновый режим,
вновь предоставляя пользователю управлять терминалом, но возвращающий настройки терминала к исходным.
## Авторы
Антипенко Дмитрий Андреевич [C22-712] - https://github.com/ada-dmitry/
Кузнецов Даниил Евгеньевич [C22-712]
Никитин Михаил Андреевич [C22-712]
Ускова Екатерина Александровна [C22-712]
+9 -1
View File
@@ -1,3 +1,5 @@
#include <stdbool.h>
extern double a, b, eps, x, *pa, *pb, *px;
extern short method, *mth, sig_flag;
extern struct termios default_term, modif_term;
@@ -20,4 +22,10 @@ double numerical_derivative(double x);
void __exit();
void show_grapgh();
void input_diap();
void change_diap();
void change_diap();
// double input_number(char ch);
bool is_digit(char c);
bool is_sign(char c);
bool is_dot(char c);
double read_parse(char ch);
bool is_enter(char c);
+102 -41
View File
@@ -4,6 +4,8 @@
#include <math.h>
#include <termios.h>
#include <stdio_ext.h>
#include <ctype.h>
#include <stdbool.h>
#include "declare.h"
@@ -15,7 +17,6 @@ double f(double x) // Функция, заданная пользователе
void show_grapgh()
{
char func[100] = "x+20";
tcsetattr(0, TCSANOW, &modif_term);
// Подключение GNU Plot
FILE *gp = popen("gnuplot -persist", "w");
@@ -34,7 +35,6 @@ void show_grapgh()
getchar();
sig_flag = 0;
fprintf(gp, "exit\n");
tcsetattr(0, TCSANOW, &default_term);
return;
}
@@ -176,53 +176,29 @@ void __exit()
void input_diap()
{
double tmp;
char input[50];
sig_flag = 1;
system("clear");
printf("\n\nТекущие значения: [%lf : %lf] eps = %lf\n\n\
Введите левую границу отрезка и нажмите Enter (по умолчанию: %lf): ",
printf("\n\nТекущие значения: [%g] : %g | eps = %g\n\n\
Введите левую границу отрезка и нажмите Enter (по умолчанию: %g): ",
*pa, *pb, eps, *pa);
fgets(input, sizeof(input), stdin);
if (input[0] == '\n')
{
*pa = A; // значение по умолчанию
}
else
{
sscanf(input, "%lf", pa);
}
*pa = read_parse('A');
system("clear");
printf("\n\nТекущие значения: [%lf : %lf] eps = %lf\n\n\
Введите правую границу отрезка и нажмите Enter (по умолчанию: %lf): ",
printf("\nТекущие значения: %g : [%g] | eps = %g\n\n\
Введите правую границу отрезка и нажмите Enter (по умолчанию: %g): ",
*pa, *pb, eps, *pb);
fgets(input, sizeof(input), stdin);
if (input[0] == '\n')
{
*pb = B; // значение по умолчанию
}
else
{
sscanf(input, "%lf", pb);
}
*pb = read_parse('B');
system("clear");
printf("\n\nТекущие значения: [%lf : %lf] eps = %lf\n\n\
Введите точность вычисления и нажмите Enter (по умолчанию: %lf): ",
printf("\nТекущие значения: %g : %g | eps = [%g]\n\n\
Введите точность вычисления и нажмите Enter (по умолчанию: %g): ",
*pa, *pb, eps, eps);
fgets(input, sizeof(input), stdin);
if (input[0] == '\n')
{
eps = EPS; // значение по умолчанию
}
else
{
sscanf(input, "%lf", &eps);
}
eps = read_parse('E');
system("clear");
__fpurge(stdin);
printf("\nВыберите метод вычисления корня и нажмите Enter:\
@@ -242,7 +218,6 @@ void input_diap()
sig_flag = 0;
printf("В указанных границах нуля функции не существует.\n");
printf("Поменяйте границы\n");
// choose_path();
change_diap();
}
if (eps < 0) // Если пользователь указал отрицательную точность
@@ -273,16 +248,18 @@ void change_diap()
// Возврат к обычному выводу
tcsetattr(0, TCSANOW, &default_term);
printf("Введите новые значения границ a и b: ");
system("clear");
scanf("%lf%lf", pa, pb);
printf("Введите новое значение левой границы: ");
*pa = read_parse('A');
printf("Введите новое значение правой границы: ");
*pb = read_parse('B');
if (f(*pa) * f(*pb) > 0)
{
printf("\nВ указанных границах нуля функции не существует.\n");
printf("Поменяйте границы\n");
choose_path();
// change_diap();
}
if (*pa == *pb)
{
@@ -300,4 +277,88 @@ void change_diap()
sig_flag = 0;
return;
}
}
bool is_digit(char c)
{
return (c >= '0' && c <= '9');
}
bool is_sign(char c)
{
return (c == '+' || c == '-');
}
bool is_dot(char c)
{
return (c == '.');
}
bool is_enter(char c)
{
return (c == '\n');
}
double read_parse(char ch)
{
char input[50];
double number;
__fpurge(stdin);
fgets(input, sizeof(input), stdin);
__fpurge(stdin);
int i = 0;
bool is_valid = true;
bool has_dot = false;
// Проверка первого символа, который может быть знаком или переносом строки
if (is_sign(input[0]))
{
i++;
}
else if (is_enter(input[0]))
{
switch (ch)
{
case 'A':
return A;
case 'B':
return B;
case 'E':
return EPS;
}
}
// Проверка символов, формирующих цифры числа
while (input[i] != '\0')
{
if (is_digit(input[i]))
{
i++;
continue;
}
else if (is_dot(input[i]) && !has_dot)
{
has_dot = true;
i++;
continue;
}
else
{
is_valid = false;
break;
}
}
if (is_valid)
{
number = atof(input);
return number;
}
else
{
printf("Ошибка: некорректный ввод\nЗавершение выполнения программы...\n");
__exit();
}
return 1;
}
+4 -4
View File
@@ -53,22 +53,22 @@ int main()
system("clear");
if (*mth == 0)
{
printf("Fork\n");
printf("\nFork\n");
fork_method();
}
else if (*mth == 1)
{
printf("Chord\n");
printf("\nChord\n");
chord_method();
}
else if (*mth == 2)
{
printf("Newton\n");
printf("\nNewton\n");
newton_method();
}
else
{
printf("Fork\n");
printf("\nFork\n");
fork_method();
}
Binary file not shown.
Binary file not shown.