Для большинства задач алгоритмы их решения являются довольно большими и громоздкими. При программировании нужно стараться получить программу удобочитаемую, высокоэффективную и легко модифицируемую. Для этого производят декомпозицию сложного алгоритма поставленной задачи, т.е. его разбивка на отдельные более простые подзадачи, затем декомпозиция подзадач и т.д. Для этого используют приемы процедурного программирования.
Один из основных приемов - разбивка алгоритма на отдельные функции и/или модули, используя функциональную и/или модульную декомпозиции соответственно.
Функциональная декомпозиция- метод разбивки большой программы на отдельные функции, т.е. общий алгоритм - на отдельные шаги, которые потом и оформляют в виде отдельных функций.
Алгоритм декомпозиции можно представить следующим образом:
- программу делать как последовательность более мелких действий;
- каждую детализацию подробно описать;
- каждую детализацию представить в виде абстрактного оператора, который должен однозначно определять нужное действие, и в конечном итоге эти абстрактные действия заменятся на группы операторов выбранного языка программирования.
При этом надо помнить, что каждая детализация – это один из вариантов решения, и поэтому необходимо проверять, что :
- решение частных задач приводит решению общей задачи;
- выбранная последовательность действий разумна;
- построенная декомпозиция позволяет получать команды, легко реализуемые на выбранном языке программирования.
Единицей компиляции в языке Си является отдельный файл (программный модуль). Модульная декомпозиция представляет собой разбиение программы на несколько отдельных файлов, каждый из которых решает отдельную конкретную задачу и, как правило, облегчает процесс ее работы. Кроме того, код программы, разделенный на отдельные файлы, позволяет части этого кода использовать в других программах.
Пример модульной декомпозиции кода Си:
Язык Си относится к языкам высокого уровня, т.е. предназначенным для записи программы в форме, удобной для человека и не "привязанной" к конкретному типу машин. Исходный текст программы на Си, введенный с помощью клавиатуры в память компьютера - исходный код (source code, обычно хранится в файлах с расширением *.cpp). Он может быть разбит на смысловые части (функции и т.д.). Если эти части хранятся в разных файлах, то каждый такой файл называется исходным модулем.
Компилятор - программа, осуществляющая перевод программ с языка высокого уровня (приближенного к человеку) на язык более низкого уровня (близкий к ЭВМ), или язык машинных команд. Компиляция программы на языке Си состоит из двух этапов: начальной обработки, выполняемой т.н. препроцессором, и собственно компиляции. Результат обработки исходного модуля компилятором - объектный код (object code, обычно хранится в файлах с расширением *.obj). В большинстве случаев компилятор переводит на машинный язык каждую функцию по отдельности, не связывая их друг с другом и с библиотечными функциями; поэтому объектный код не может еще быть выполнен.
Лишь вторая специальная программа - редактор связей (Linker) - создает исполняемый (абсолютный, загрузочный) код, "связывая" между собой функции и места их использования (вызова), подключая при этом и библиотечные функции. Linker еще называют компоновщиком, т.к. он объединяет программные модули в новый модуль, пригодный для выполнения - загрузочный модуль (Load module, расширение *.exe).
Большинство сред программирования по команде "Запуск программы" ("Run") автоматически выполняют все указанные этапы. Однако знать их различие все же стоит, чтобы при возникновении ошибок лучше понимать их причины. По тексту сообщения об ошибке обычно четко видно, на каком этапе она произошла.