Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Industrial programming >> Язык C

Четыре проверенных паттерна пользовательских функций в C

Четыре проверенных паттерна пользовательских функций в C

Изучите четыре различных способа реализации пользовательской функции проверки простоты числа и выявите, какой подход даёт наибольшую ясность и переиспользуемость.

Ниже четыре полные программы демонстрируют, как одна и та же логическая задача может быть выражена с разными сигнатурами функций. Все четыре дают идентичный вывод, но дизайнерские решения различаются, иллюстрируя ключевые компромиссы в дизайне функций.


Пример 1: Без аргументов, без возвращаемого значения

#include <stdio.h>
void checkPrimeNumber();
int main() {
    checkPrimeNumber(); // аргумент не передаётся
    return 0;
}
// Возвращаемый тип void — не возвращает значение
void checkPrimeNumber() {
    int n, i, flag = 0;
    printf("Enter a positive integer: ");
    scanf("%d", &n);
    for(i = 2; i <= n/2; ++i) {
        if(n % i == 0) { flag = 1; }
    }
    if (flag == 1) printf("%d is not a prime number.", n);
    else printf("%d is a prime number.", n);
}

Функция checkPrimeNumber() отвечает за ввод пользователя, проверку на простоту и печать результата. Поскольку возвращаемый тип void, она сообщает результат только через побочные эффекты.


Пример 2: Без аргументов, но с возвращаемым значением

#include <stdio.h>
int getInteger();
int main() {
    int n, i, flag = 0;
    // аргумент не передаётся
    n = getInteger();
    for(i = 2; i <= n/2; ++i) {
        if(n % i == 0) { flag = 1; break; }
    }
    if (flag == 1) printf("%d is not a prime number.", n);
    else printf("%d is a prime number.", n);
    return 0;
}
// Возвращает целое, введённое пользователем
int getInteger() {
    int n;
    printf("Enter a positive integer: ");
    scanf("%d", &n);
    return n;
}

Здесь getInteger() инкапсулирует рутину ввода и возвращает значение в main, который затем выполняет проверку на простоту. Это разделение делает шаг ввода переиспользуемым в разных контекстах.


Пример 3: Аргумент передан, нет возвращаемого значения

#include <stdio.h>
void checkPrimeAndDisplay(int n);
int main() {
    int n;
    printf("Enter a positive integer: ");
    scanf("%d", &n);
    // n передаётся в функцию
    checkPrimeAndDisplay(n);
    return 0;
}
// Возвращаемый тип void — не возвращает значение
void checkPrimeAndDisplay(int n) {
    int i, flag = 0;
    for(i = 2; i <= n/2; ++i) {
        if(n % i == 0) { flag = 1; break; }
    }
    if(flag == 1) printf("%d is not a prime number.", n);
    else printf("%d is a prime number.", n);
}

В этом паттерне ответственность за вывод перемещена в вспомогательную функцию. Хотя это делает main стройным, функция теперь связывает алгоритм с I/O, снижая переиспользуемость.


Пример 4: Аргумент передан и есть возвращаемое значение

#include <stdio.h>
int checkPrimeNumber(int n);
int main() {
    int n, flag;
    printf("Enter a positive integer: ");
    scanf("%d", &n);
    // n передаётся в checkPrimeNumber()
    // возвращённое значение присваивается flag
    flag = checkPrimeNumber(n);
    if(flag == 1) printf("%d is not a prime number", n);
    else printf("%d is a prime number", n);
    return 0;
}
// int возвращается из функции
int checkPrimeNumber(int n) {
    int i;
    for(i = 2; i <= n/2; ++i) {
        if(n % i == 0) return 1;
    }
    return 0;
}

Этот дизайн изолирует алгоритм и возвращает простой флаг статуса. Вызывающий код решает, как представить результат, что делает функцию высокопереиспользуемой в библиотеках или крупных приложениях.


Выбор оптимального паттерна

Хотя все четыре реализации дают один вывод, наиболее поддерживаемый и тестируемый подход — Пример 4: передача числа как аргумента и возврат булево-подобного флага. Этот паттерн следует принципу единственной ответственности, позволяет юнит-тестирование checkPrimeNumber без I/O зависимостей и легко интегрируется в более сложные системы.

В конечном счёте, выбор зависит от архитектуры проекта. Если функция должна взаимодействовать с пользователем напрямую, Пример 3 может подойти. Для библиотечного кода или сервисов, где I/O обрабатывается отдельно, Пример 4 даёт максимальную гибкость.

Резюме паттернов

ПаттернАргументыВозвратПлюсыМинусы
1. Нет аргументов, нет возврата—voidПростота для скриптовЖёсткая связь с I/O, нетестируемо
2. Нет аргументов, есть возврат—TИнкапсуляция вводаВвод всё равно жёстко задан
3. Есть аргументы, нет возвратаTvoidЧистый main, разделение логикиСвязка алгоритма с выводом
4. Есть аргументы, есть возвратTTМаксимальная переиспользуемость, тестируемость, SRPБольше кода в main

Язык C

  1. Освоение пространств имен в C#: организация, область видимости и лучшие практики
  2. Типы данных в C: int, float, char и другие — полное руководство
  3. Операторы в C: исчерпывающее руководство
  4. Стандартные библиотечные функции в C: практическое руководство
  5. Переменные и типы данных в C++: подробное руководство по int, double, char, string, bool
  6. Указатели в C: полное руководство по типам, использованию и лучшим практикам
  7. Освоение программирования на C: подробное руководство для начинающих
  8. Типы данных в C: полное руководство по целочисленным, вещественным и производным типам
  9. Функции в C: объявление, определение, вызов, аргументы (по значению и по ссылке), рекурсия
  10. Функции с переменным числом аргументов в C: практическое руководство