From 48e777f482fe71bcfee4330dc7dbaf2e5ea39282 Mon Sep 17 00:00:00 2001 From: b1sted <189896017+b1sted@users.noreply.github.com> Date: Tue, 3 Jun 2025 00:16:29 +0300 Subject: [PATCH 1/5] feat(params): Centralize configuration with constants Replaced hardcoded magic numbers, simulation parameters, file paths, and array sizes with named constants (e.g., `TN_PARAM`, `FILE_PATH_ARRAY_T`). This change also simplifies `forming_Uvx` and `forming_Uvix` function signatures, as their configuration parameters are now internal constants. Improves readability, maintainability, and centralizes configuration. --- include/constants.h | 62 +++++++++++++++++++++++++++++++++++++++++++ include/forming.h | 4 +-- src/file.c | 9 ++++--- src/forming.c | 29 ++++++++++---------- src/input.c | 5 ++-- src/output.c | 3 ++- src/parameter.c | 24 +++++++---------- src/signal_analysis.c | 16 ++++++----- 8 files changed, 106 insertions(+), 46 deletions(-) create mode 100644 include/constants.h diff --git a/include/constants.h b/include/constants.h new file mode 100644 index 0000000..00caa74 --- /dev/null +++ b/include/constants.h @@ -0,0 +1,62 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2025 Nikita Mandrykin. All rights reserved. + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef CONSTANTS_H +#define CONSTANTS_H + +// Для input.c +#define INPUT_SIZE 10 + +// Для parameter.c и signal_analysis.c +#define ARRAY_SIZE 1500 + +// Для parameter.c +#define EPSILON 0.01f +#define INITIAL_CURRENT_PRECISION 1.0f +#define PREV_PARAMETER_INITIAL 1e10f +#define INITIAL_POINTS 11 + +// Параметры для функции forming_Uvx (используются в forming.c) +#define T1_PARAM 10.0f +#define T2_PARAM 15.0f +#define T3_PARAM 45.0f +#define A_PARAM 20.0f +#define B_PARAM 0.5f +#define C_PARAM 17.0f + +// Параметры для функции forming_Uvix (используются в forming.c) +#define UVX1_PARAM 20.0f +#define D_PARAM 2.0f +#define E_PARAM -5.0f + +// Параметры для функции forming_time (используются в forming.c) +#define TN_PARAM 5.0f +#define TK_PARAM 50.0f + +// Пути к файлам +#define FILE_PATH_ARRAY_T "data/array_t.txt" +#define FILE_PATH_ARRAY_UVX "data/array_Uvx.txt" +#define FILE_PATH_ARRAY_UVIX "data/array_Uvix.txt" +#define FILE_PATH_ZAST "data/zast.txt" + +#endif // CONSTANTS_H diff --git a/include/forming.h b/include/forming.h index ffce02c..8111db4 100644 --- a/include/forming.h +++ b/include/forming.h @@ -25,7 +25,7 @@ #define FORMING_H void forming_time(int n, float *t, float *dt); -void forming_Uvx(int n, float *t, float *Uvx, float t1, float t2, float t3, float a, float b, float c); -void forming_Uvix(int n, float *Uvx, float *Uvix, float Uvx1, float a, float b); +void forming_Uvx(int n, float *t, float *Uvx); +void forming_Uvix(int n, float *Uvx, float *Uvix); #endif // FORMING_H diff --git a/src/file.c b/src/file.c index 026eb0b..009a61f 100644 --- a/src/file.c +++ b/src/file.c @@ -25,13 +25,14 @@ #include #include "file.h" +#include "constants.h" // Функция для открытия файлов для последующей записи в них информации void open_output_files(FILE **f1, FILE **f2, FILE **f3) { - *f1 = fopen("data/array_t.txt", "w"); - *f2 = fopen("data/array_Uvx.txt", "w"); - *f3 = fopen("data/array_Uvix.txt", "w"); - + *f1 = fopen(FILE_PATH_ARRAY_T, "w"); + *f2 = fopen(FILE_PATH_ARRAY_UVX, "w"); + *f3 = fopen(FILE_PATH_ARRAY_UVIX, "w"); + // Проверка успешности открытия файлов if (*f1 == NULL || *f2 == NULL || *f3 == NULL) { perror("Ошибка при открытии файлов"); diff --git a/src/forming.c b/src/forming.c index 67035c6..e5df080 100644 --- a/src/forming.c +++ b/src/forming.c @@ -22,39 +22,38 @@ */ #include "forming.h" +#include "constants.h" // Функция формирования массива времени void forming_time(int n, float *t, float *dt) { - float tn = 5, tk = 50; - - *dt = (tk - tn) / (n - 1); + *dt = (TK_PARAM - TN_PARAM) / (n - 1); for (int i = 0; i < n; i++) { - t[i] = tn + i * (*dt); + t[i] = TN_PARAM + i * (*dt); } } // Функция формирования массива Uvx -void forming_Uvx(int n, float *t, float *Uvx, float t1, float t2, float t3, float a, float b, float c) { +void forming_Uvx(int n, float *t, float *Uvx) { for (int i = 0; i < n; i++) { - if (t[i] <= t1) { + if (t[i] <= T1_PARAM) { Uvx[i] = 0; - } else if (t1 < t[i] && t[i] <= t2) { - Uvx[i] = a * (t[i] - t1); - } else if (t2 < t[i] && t[i] <= t3) { - Uvx[i] = a * (t2 - t1) - b * (t[i] - t2); + } else if (T1_PARAM < t[i] && t[i] <= T2_PARAM) { + Uvx[i] = A_PARAM * (t[i] - T1_PARAM); + } else if (T2_PARAM < t[i] && t[i] <= T3_PARAM) { + Uvx[i] = A_PARAM * (T2_PARAM - T1_PARAM) - B_PARAM * (t[i] - T2_PARAM); } else { - Uvx[i] = a * (t2 - t1) - b * (t3 - t1) - c * (t[i] - t3); + Uvx[i] = A_PARAM * (T2_PARAM - T1_PARAM) - B_PARAM * (T3_PARAM - T1_PARAM) - C_PARAM * (t[i] - T3_PARAM); } } } // Функция формирования массива Uvix -void forming_Uvix(int n, float *Uvx, float *Uvix, float Uvx1, float a, float b) { +void forming_Uvix(int n, float *Uvx, float *Uvix) { for (int i = 0; i < n; i++) { - if (Uvx[i] <= Uvx1) { - Uvix[i] = a * Uvx[i] + b; + if (Uvx[i] <= UVX1_PARAM) { + Uvix[i] = D_PARAM * Uvx[i] + E_PARAM; } else { - Uvix[i] = a * Uvx1 + b; + Uvix[i] = D_PARAM * UVX1_PARAM + E_PARAM; } } } diff --git a/src/input.c b/src/input.c index c0cba80..4878175 100644 --- a/src/input.c +++ b/src/input.c @@ -26,8 +26,7 @@ #include #include "input.h" - -#define INPUT_SIZE 10 +#include "constants.h" // Функция для ввода n int input_n() { @@ -55,7 +54,7 @@ bool ask_user_continue(void) { while (1) { printf("Хотите продолжить? (да/нет): "); - // Считываем строку ввода с ограничением + // Считываем строку ввода с ограничением. "%9s" для INPUT_SIZE == 10 (оставляет место для '\0') if (scanf("%9s", input) != 1) { while (getchar() != '\n'); // Если произошла ошибка ввода, очищаем буфер continue; diff --git a/src/output.c b/src/output.c index 541e544..817c55e 100644 --- a/src/output.c +++ b/src/output.c @@ -25,10 +25,11 @@ #include "output.h" #include "file.h" +#include "constants.h" // Функция вывода заставки из файла void print_banner() { - FILE *fp = fopen("data/zast.txt", "r"); + FILE *fp = fopen(FILE_PATH_ZAST, "r"); if (!fp) { perror("Не удалось открыть файл заставки"); diff --git a/src/parameter.c b/src/parameter.c index 9d043fd..32608bf 100644 --- a/src/parameter.c +++ b/src/parameter.c @@ -26,8 +26,7 @@ #include "parameter.h" #include "forming.h" - -#define N 1500 +#include "constants.h" // Функция расчета длительности переднего фронта импульса float calc_leading_edge(int n, float *U, float dt) { @@ -53,29 +52,26 @@ float calc_leading_edge(int n, float *U, float dt) { // Функция расчета параметра с заданной точностью void calculate_with_precision() { - float epsilon = 0.01; // Требуемая точность (1%) - float current_precision = 1.0; // Текущая погрешность - float prev_parameter = 1e10; // Начальное (очень большое) значение - int n = 11; // Начальное количество точек + float current_precision = INITIAL_CURRENT_PRECISION; // Текущая погрешность + float prev_parameter = PREV_PARAMETER_INITIAL; // Начальное (очень большое) значение + int n = INITIAL_POINTS; // Начальное количество точек - float current_parameter, t[N], Uvx[N], Uvix[N], dt; + float current_parameter, t[ARRAY_SIZE], Uvx[ARRAY_SIZE], Uvix[ARRAY_SIZE], dt; printf("\nЗаданный параметр: расчет длительности заднего фронта для Uвых\n"); - while (current_precision > epsilon) { + while (current_precision > EPSILON) { // Формирование массивов forming_time(n, t, &dt); - float t1 = 10, t2 = 15, t3 = 45, a = 20, b = 0.5, c = 17; - forming_Uvx(n, t, Uvx, t1, t2, t3, a, b, c); - float Uvx1 = 20, d = 2, e = -5; - forming_Uvix(n, Uvx, Uvix, Uvx1, d, e); + forming_Uvx(n, t, Uvx); + forming_Uvix(n, Uvx, Uvix); // Расчет параметра current_parameter = calc_leading_edge(n, Uvix, dt); // Расчет погрешности - if (prev_parameter != 1e10) { + if (prev_parameter != PREV_PARAMETER_INITIAL) { current_precision = fabs(prev_parameter - current_parameter) / current_parameter; } @@ -86,7 +82,7 @@ void calculate_with_precision() { n *= 2; } - if (n >= N) { + if (n >= ARRAY_SIZE) { printf("Предупреждение: достигнут максимальный размер массива без достижения требуемой точности\n"); } else { printf("Итоговое значение параметра: %.6f (точность: %.2f%%)\n", current_parameter, current_precision * 100); diff --git a/src/signal_analysis.c b/src/signal_analysis.c index 9f96443..e35b527 100644 --- a/src/signal_analysis.c +++ b/src/signal_analysis.c @@ -29,11 +29,10 @@ #include "file.h" #include "forming.h" #include "parameter.h" - -#define N 1500 +#include "constants.h" int main() { - float t[N], Uvx[N], Uvix[N], dt; + float t[ARRAY_SIZE], Uvx[ARRAY_SIZE], Uvix[ARRAY_SIZE], dt; int n, choice; bool continueProgram = true; @@ -65,18 +64,21 @@ int main() { case 1: n = input_n(); + // Формирование массива времени t и расчет шага dt forming_time(n, t, &dt); - float t1 = 10, t2 = 15, t3 = 45, a = 20, b = 0.5, c = 17; - forming_Uvx(n, t, Uvx, t1, t2, t3, a, b, c); + // Формирование массива входного напряжения Uvx + forming_Uvx(n, t, Uvx); - float Uvx1 = 20, d = 2, e = -5; - forming_Uvix(n, Uvx, Uvix, Uvx1, d, e); + // Формирование массива выходного напряжения Uvix по Uvx + forming_Uvix(n, Uvx, Uvix); + // Вывод сформированных данных в виде таблицы forming_table(n, t, Uvx, Uvix); break; case 2: + // Расчет параметра (длительности переднего фронта) с заданной точностью calculate_with_precision(); break; case 3: From f965630623afae2d759eb5ea5c69c8eb567fd156 Mon Sep 17 00:00:00 2001 From: b1sted <189896017+b1sted@users.noreply.github.com> Date: Tue, 3 Jun 2025 00:20:33 +0300 Subject: [PATCH 2/5] fix(parameter): Correct calculation description to leading edge Updated comments and print statements in `calc_leading_edge` and `calculate_with_precision` to correctly refer to the calculation of the "leading edge duration" instead of "trailing edge duration". --- src/parameter.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/parameter.c b/src/parameter.c index 32608bf..8246624 100644 --- a/src/parameter.c +++ b/src/parameter.c @@ -41,7 +41,7 @@ float calc_leading_edge(int n, float *U, float dt) { float U1 = Umin + 0.9 * (Umax - Umin); float U2 = Umin + 0.1 * (Umax - Umin); - // Считаем длительность заднего фронта + // Считаем длительность переднего фронта float duration = 0; for (int i = 0; i < n - 1; i++) { if (U[i] < U1 && U[i] > U2 && U[i + 1] > U[i]) duration += dt; @@ -58,7 +58,7 @@ void calculate_with_precision() { float current_parameter, t[ARRAY_SIZE], Uvx[ARRAY_SIZE], Uvix[ARRAY_SIZE], dt; - printf("\nЗаданный параметр: расчет длительности заднего фронта для Uвых\n"); + printf("\nЗаданный параметр: расчет длительности переднего фронта для Uвых\n"); while (current_precision > EPSILON) { // Формирование массивов From 84bbaeb26d9a18dfb7ce56f63911818f3a7c99ed Mon Sep 17 00:00:00 2001 From: b1sted <189896017+b1sted@users.noreply.github.com> Date: Fri, 11 Jul 2025 14:59:21 +0300 Subject: [PATCH 3/5] style(signal_analysis): fix indentation in switch statement Corrected the indentation within the main function's switch block to improve code readability and maintain a consistent style. No functional changes have been made. --- src/signal_analysis.c | 60 +++++++++++++++++++++---------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/src/signal_analysis.c b/src/signal_analysis.c index e35b527..05604df 100644 --- a/src/signal_analysis.c +++ b/src/signal_analysis.c @@ -61,36 +61,36 @@ int main() { } switch (choice) { - case 1: - n = input_n(); - - // Формирование массива времени t и расчет шага dt - forming_time(n, t, &dt); - - // Формирование массива входного напряжения Uvx - forming_Uvx(n, t, Uvx); - - // Формирование массива выходного напряжения Uvix по Uvx - forming_Uvix(n, Uvx, Uvix); - - // Вывод сформированных данных в виде таблицы - forming_table(n, t, Uvx, Uvix); - - break; - case 2: - // Расчет параметра (длительности переднего фронта) с заданной точностью - calculate_with_precision(); - break; - case 3: - // Открываем файлы для записи - open_output_files(&f1, &f2, &f3); - - // Записываем данные в файлы - output_in_file(f1, f2, f3, n, t, Uvx, Uvix); - - // Закрываем файлы после записи - close_output_files(f1, f2, f3); - break; + case 1: + n = input_n(); + + // Формирование массива времени t и расчет шага dt + forming_time(n, t, &dt); + + // Формирование массива входного напряжения Uvx + forming_Uvx(n, t, Uvx); + + // Формирование массива выходного напряжения Uvix по Uvx + forming_Uvix(n, Uvx, Uvix); + + // Вывод сформированных данных в виде таблицы + forming_table(n, t, Uvx, Uvix); + + break; + case 2: + // Расчет параметра (длительности переднего фронта) с заданной точностью + calculate_with_precision(); + break; + case 3: + // Открываем файлы для записи + open_output_files(&f1, &f2, &f3); + + // Записываем данные в файлы + output_in_file(f1, f2, f3, n, t, Uvx, Uvix); + + // Закрываем файлы после записи + close_output_files(f1, f2, f3); + break; } printf("\n"); From 0b62e50399745ff2a4e69c94abff6c6628a5de1c Mon Sep 17 00:00:00 2001 From: b1sted <189896017+b1sted@users.noreply.github.com> Date: Fri, 11 Jul 2025 15:48:22 +0300 Subject: [PATCH 4/5] refactor(input): abstract user response handling to a dictionary module MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaced hardcoded string comparisons for 'yes'/'no' answers with a more robust and extensible system. This change introduces a `response_dictionary` module to centralize the parsing of user responses. The `ask_user_continue` function now calls `get_response_type_by_keyword` to receive a structured `ResponseType` enum. This approach: - Eliminates magic strings ("да", "нет") from the input logic. - Improves readability by using a clean `switch` statement. - Makes it easy to add new response keywords (e.g., 'y', 'yes') in the future by modifying only the dictionary module. --- include/response_dictionary.h | 43 ++++++++++++++++++++++++++++ src/input.c | 19 ++++++++---- src/response_dictionary.c | 54 +++++++++++++++++++++++++++++++++++ 3 files changed, 110 insertions(+), 6 deletions(-) create mode 100644 include/response_dictionary.h create mode 100644 src/response_dictionary.c diff --git a/include/response_dictionary.h b/include/response_dictionary.h new file mode 100644 index 0000000..ce7d72e --- /dev/null +++ b/include/response_dictionary.h @@ -0,0 +1,43 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2025 Nikita Mandrykin. All rights reserved. + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef RESPONSE_DICTIONARY_H +#define RESPONSE_DICTIONARY_H + +typedef enum { + RESPONSE_UNKNOWN, + RESPONSE_AFFIRMATIVE, + RESPONSE_NEGATIVE +} ResponseType; + +typedef struct { + const char *keyword_text; + ResponseType type; +} KeywordMapping; + +extern const KeywordMapping RESPONSE_DICTIONARY[]; +extern const int DICTIONARY_SIZE; + +ResponseType get_response_type_by_keyword(const char* input); + +#endif // RESPONSE_DICTIONARY_H \ No newline at end of file diff --git a/src/input.c b/src/input.c index 4878175..6a0899c 100644 --- a/src/input.c +++ b/src/input.c @@ -27,6 +27,7 @@ #include "input.h" #include "constants.h" +#include "response_dictionary.h" // Функция для ввода n int input_n() { @@ -64,12 +65,18 @@ bool ask_user_continue(void) { int c; while ((c = getchar()) != '\n' && c != EOF); - if ((strcmp(input, "да") == 0) || (strcmp(input, "ДА") == 0)) { - return true; - } else if ((strcmp(input, "нет") == 0) || (strcmp(input, "НЕТ") == 0)) { - return false; - } else { - printf("Некорректный ввод. Пожалуйста, введите 'да' или 'нет'.\n"); + ResponseType result = get_response_type_by_keyword(input); + + switch (result) { + case RESPONSE_AFFIRMATIVE: + return true; + break; + case RESPONSE_NEGATIVE: + return false; + break; + case RESPONSE_UNKNOWN: + printf("Некорректный ввод. Пожалуйста, введите 'да' или 'нет'.\n"); + break; } } diff --git a/src/response_dictionary.c b/src/response_dictionary.c new file mode 100644 index 0000000..463d12b --- /dev/null +++ b/src/response_dictionary.c @@ -0,0 +1,54 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2025 Nikita Mandrykin. All rights reserved. + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include + +#include "response_dictionary.h" + +const KeywordMapping RESPONSE_DICTIONARY[] = { + // Утвердительные ответы + {"да", RESPONSE_AFFIRMATIVE}, + {"Да", RESPONSE_AFFIRMATIVE}, + {"дА", RESPONSE_AFFIRMATIVE}, + {"ДА", RESPONSE_AFFIRMATIVE}, + + // Отрицательные ответы + {"нет", RESPONSE_NEGATIVE}, + {"Нет", RESPONSE_NEGATIVE}, + {"нЕт", RESPONSE_NEGATIVE}, + {"неТ", RESPONSE_NEGATIVE}, + {"НЕт", RESPONSE_NEGATIVE}, + {"нЕТ", RESPONSE_NEGATIVE}, + {"НЕТ", RESPONSE_NEGATIVE} +}; + +const int DICTIONARY_SIZE = sizeof(RESPONSE_DICTIONARY) / sizeof(RESPONSE_DICTIONARY[0]); + +ResponseType get_response_type_by_keyword(const char *input) { + for (int i = 0; i < DICTIONARY_SIZE; i++) { + if (strcmp(input, RESPONSE_DICTIONARY[i].keyword_text) == 0) { + return RESPONSE_DICTIONARY[i].type; + } + } + return RESPONSE_UNKNOWN; +} From 9fe204fb09cba3d8ad89eece6b9e39689a07e74e Mon Sep 17 00:00:00 2001 From: b1sted <189896017+b1sted@users.noreply.github.com> Date: Fri, 11 Jul 2025 16:22:23 +0300 Subject: [PATCH 5/5] refactor(constants): encapsulate module-specific constants Moved constants that are private to a single module from the global `constants.h` header into their respective implementation files. These constants were converted from preprocessor `#define` macros to `static const` variables to limit their scope. This change improves encapsulation and reduces global namespace pollution. Key benefits: - **Encapsulation:** Modules no longer expose their internal numerical parameters globally. - **Cohesion:** Constants now live alongside the code that uses them. - **Type Safety:** `static const` provides type checking, which is safer than `#define`. Constants that are genuinely shared across multiple modules, such as `ARRAY_SIZE` and file paths, remain in the global `constants.h` file. --- include/constants.h | 31 +++---------------------------- src/forming.c | 18 +++++++++++++++++- src/input.c | 3 +++ src/parameter.c | 12 ++++++++++++ 4 files changed, 35 insertions(+), 29 deletions(-) diff --git a/include/constants.h b/include/constants.h index 00caa74..fb731b5 100644 --- a/include/constants.h +++ b/include/constants.h @@ -24,36 +24,11 @@ #ifndef CONSTANTS_H #define CONSTANTS_H -// Для input.c -#define INPUT_SIZE 10 - -// Для parameter.c и signal_analysis.c +// Максимальный размер массивов для данных. +// Используется в main для выделения памяти и в других модулях для проверки границ. #define ARRAY_SIZE 1500 -// Для parameter.c -#define EPSILON 0.01f -#define INITIAL_CURRENT_PRECISION 1.0f -#define PREV_PARAMETER_INITIAL 1e10f -#define INITIAL_POINTS 11 - -// Параметры для функции forming_Uvx (используются в forming.c) -#define T1_PARAM 10.0f -#define T2_PARAM 15.0f -#define T3_PARAM 45.0f -#define A_PARAM 20.0f -#define B_PARAM 0.5f -#define C_PARAM 17.0f - -// Параметры для функции forming_Uvix (используются в forming.c) -#define UVX1_PARAM 20.0f -#define D_PARAM 2.0f -#define E_PARAM -5.0f - -// Параметры для функции forming_time (используются в forming.c) -#define TN_PARAM 5.0f -#define TK_PARAM 50.0f - -// Пути к файлам +// Пути к внешним файлам данных #define FILE_PATH_ARRAY_T "data/array_t.txt" #define FILE_PATH_ARRAY_UVX "data/array_Uvx.txt" #define FILE_PATH_ARRAY_UVIX "data/array_Uvix.txt" diff --git a/src/forming.c b/src/forming.c index e5df080..c7d876c 100644 --- a/src/forming.c +++ b/src/forming.c @@ -22,7 +22,23 @@ */ #include "forming.h" -#include "constants.h" + +// Параметры для функции forming_time +static const float TN_PARAM = 5.0f; +static const float TK_PARAM = 50.0f; + +// Параметры для функции forming_Uvx +static const float T1_PARAM = 10.0f; +static const float T2_PARAM = 15.0f; +static const float T3_PARAM = 45.0f; +static const float A_PARAM = 20.0f; +static const float B_PARAM = 0.5f; +static const float C_PARAM = 17.0f; + +// Параметры для функции forming_Uvix +static const float UVX1_PARAM = 20.0f; +static const float D_PARAM = 2.0f; +static const float E_PARAM = -5.0f; // Функция формирования массива времени void forming_time(int n, float *t, float *dt) { diff --git a/src/input.c b/src/input.c index 6a0899c..1c60874 100644 --- a/src/input.c +++ b/src/input.c @@ -29,6 +29,9 @@ #include "constants.h" #include "response_dictionary.h" +// Размер буфера для чтения строкового ввода от пользователя ("да"/"нет"). С запасом для '\0'. +static const int INPUT_SIZE = 10; + // Функция для ввода n int input_n() { int value; diff --git a/src/parameter.c b/src/parameter.c index 8246624..5f60712 100644 --- a/src/parameter.c +++ b/src/parameter.c @@ -28,6 +28,18 @@ #include "forming.h" #include "constants.h" +// Требуемая относительная погрешность (1% в соотв. с README), при достижении которой расчет останавливается. +static const float EPSILON = 0.01f; + +// Начальная погрешность для входа в цикл while. Просто значение > EPSILON. +static const float INITIAL_CURRENT_PRECISION = 1.0f; + +// Стартовое значение для 'prev_parameter', чтобы избежать ложной точности на первой итерации. +static const float PREV_PARAMETER_INITIAL = 1e10f; + +// Начальное количество точек 'n' для первого шага итерационного расчета. +static const int INITIAL_POINTS = 11; + // Функция расчета длительности переднего фронта импульса float calc_leading_edge(int n, float *U, float dt) { // Находим максимальное и минимальное значения