Можно ли использовать функции, чтобы оставаться организованным в C? - PullRequest
14 голосов
/ 02 июня 2011

Я относительно новый программист на C, и я заметил, что многие соглашения из других языков ООП более высокого уровня не совсем верны для C.

Можно ли нормально использовать короткие функции для организации кодирования (даже если оно будет вызываться только один раз)? Примером этого может быть 10-15 строк в чем-то вроде void init_file(void), а затем вызов его сначала в main().

Ответы [ 8 ]

20 голосов
/ 02 июня 2011

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

Кроме того, хорошо названные функции могут служить для замены комментариев, которые в противном случае были бы необходимы.Помимо обеспечения повторного использования, функции также могут (или вместо этого) предоставлять средства для организации кода и разбиения его на более мелкие блоки, которые можно легче понять.Использование функций таким образом очень похоже на создание пакетов и классов / модулей, хотя и на более детальном уровне.

15 голосов
/ 02 июня 2011

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

8 голосов
/ 02 июня 2011

Если я позволю себе немного процитировать цитату из Код завершен :

(Эти подробные сведения о причинах были сокращены и перефразированы, полное объяснение см. В полном тексте.)

Действительные причины для создания процедуры

Обратите внимание, что причины перекрываются и не предназначены для того, чтобы быть независимыми друг от друга.

  1. Уменьшить сложность - Единственная наиболее важная причина создания подпрограммы состоит в том, чтобы уменьшить сложность программы (скрыть детали, чтобы вам не приходилось думать о них).

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

  3. Избегайте дублирования кода - самая популярная причина создания подпрограммы.Экономит место и проще в обслуживании (нужно только проверить и / или изменить одно место).

  4. Скрыть последовательности - Это хорошая идея, чтобы скрыть порядок вкакие события обрабатываются.

  5. Операции со скрытыми указателями - Операции с указателями обычно трудны для чтения и подвержены ошибкам.Изоляция их в подпрограммы смещает фокус на цель операции вместо механики манипуляции указателем.

  6. Улучшение переносимости - Использование подпрограмм для изоляции непортативных возможностей.

  7. Упрощение сложных логических тестов - Добавление сложных логических тестов в функцию делает код более читабельным, потому что подробности теста отсутствуют, а название описательной функции суммируетсяЦель тестов.

  8. Улучшение производительности - Вы можете оптимизировать код в одном месте вместо нескольких.

  9. Чтобы гарантировать, что все подпрограммы малы? - Нет. При наличии множества веских причин для помещения кода в подпрограмму эта не нужна.(Это тот, который добавлен в список, чтобы убедиться, что вы обращаете внимание!)

И еще одна заключительная цитата из текста (Глава 7: Высококачественные процедуры)

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

5 голосов
/ 02 июня 2011

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

Любой стоящий компилятор сможет встроить эти вызовы для генерации эффективного кода при необходимости.

5 голосов
/ 02 июня 2011

Если группа утверждений может рассматриваться как вещь - тогда сделайте их функцией

4 голосов
/ 02 июня 2011

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

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

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

EDIT1: :

Вы также можете рассмотреть отдельные модули. Например, если вам нужно использовать стек или очередь для какого-либо приложения. Сделайте это отдельными модулями, функции которых можно вызывать из других функций. Таким образом, вы можете сохранить перекодированные часто используемые модули, запрограммировав их как группу функций, хранящихся отдельно.

1 голос
/ 04 июня 2011

Да


Я следую нескольким рекомендациям:

  1. DRY (он же DIE)
  2. Keep Cyclomatic Complexity low
  3. Функции должны помещаться в окне терминала

Каждый из этих принципов в какой-то момент потребует разбиения функции, хотя я полагаю, что # 2 может подразумевать, что две функции с прямым кодом должны быть объединены. Несколько более распространено делать то, что называется извлечением метода, чем фактически разбивать функцию на верхнюю и нижнюю половину, потому что обычная причина состоит в том, чтобы извлечь общий код, который вызывается более одного раза.

# 1 весьма полезен для принятия решений. Это то же самое, что сказать, как и я, «никогда не копировать код».

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

0 голосов
/ 02 июня 2011

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

Статья IBM Publib по встраиванию

...