| Многофайловые проекты |
|
Современные программные проекты редко ограничиваются одним исходным файлом. Распределение исходного кода программы на несколько файлов имеет ряд существенных преимуществ перед однофайловыми проектами.
Обычно процесс сборки многофайлового проекта осуществляется по следующему алгоритму:
1. Создаются и подготавливаются исходные файлы. Здесь есть одно важное : каждый файл должен быть целостным, т. е. не должен содержать незавершенных конструкций. Если в рамках проекта предполагается создание исполняемой программы, то в одном из исходных файлов должна присутствовать функция main (). 2. Создаются и подготавливаются заголовочные файлы. У заголовочных файлов особая роль: они устанавливают соглашения по использованию общих идентификаторов (имен) в различных частях программы. Если, например, функция func () реализована в файле а.с, а вызывается в файле Ь.с, то в оба файла требуется включить директивой #inciude заголовочный файл, содержащий объявление (прототип) нашей функции. Технически можно обойтись и без заголовочных файлов, но в этом случае функцию можно будет вызвать с произвольными аргументами, и компилятор, за отсутствием соглашений, не выведет ни одной ошибки. Подобный "слепой" подход потенциально опасен и в большинстве случаев свидетельствует о плохом стиле программирования. 3. Каждый исходный файл отдельно компилируется с опцией -с. В результате появляется набор объектных файлов. 4. Полученные объектные файлы соединяются компоновщиком в одну программу. Если необходимо скомпоновать несколько объектных файлов (овл.о, OBJ2. о и т. д.), то применяют следующий простой шаблон: $ gcc -о OUTPOT_FILE ОВЛ.о 0BJ2.O .... Рассмотрим программу, которая принимает в качестве аргумента строку и переводит в ней все символы в верхний регистр, т. е. заменяет все строчные буквы на заглавные. Чтобы не усложнять пример, будем преобразовывать только латинские (англоязычные) символы. Для начала создадим файл print_up.h, в котором будет находиться объявление (прототип) функции print_up{}. Эта функция переводит символы строки в верхний регистр и выводит полученный результат на экран. Файл print_up.h void print_up (const char * str) ; Итак, объявление функции print_up() устанавливает соглашение, по которому любой исходный файл, включающий print_up.h директивой #include, обязан вызвать функцию print_up() с одним и только одним аргументом типа const char*. Теперь создадим файл print_up.c, в котором будет находиться тело функции print_up (). Файл print.up с #include <ctype.h> Функция print_up () просматривает в цикле всю строку, посимвольно преобразовывая ее к верхнему регистру. Вывод также производится посимвольно. В заключение выводится символ новой строки. Функция toupper о, объявленная в файле ctype.h и являющаяся частью стандартной библиотеки языка С, возвращает переданный ей символ в верхнем регистре, если это возможно. Без дополнительных манипуляций эта функция не работает с русскими символами, но сейчас это не важно. Теперь создадим третий файл main.c, который будет содержать функцию main(), необходимую для компоновки и запуска программы. Файл main.с #include <string.h> Сначала вспомним, что аргументы командной строки передаются в программу через функцию main():
Следует помнить, что в первый аргумент командной строки обычно заносится имя программы. Таким образом, argv[0] — это имя программы, argv[1] — первый переданный при запуске аргумент, argv[2] — второй аргумент и так далее до элемента argv[argc-i]. Вообще говоря, аргументы в программу можно передавать не только из командной оболочки. Поэтому понятие "аргументы командной строки" не всегда отражает действительное положение вещей. В связи с этим, чтобы избежать неоднозначности, будем в дальнейшем пользоваться более точной формулировкой "аргументы программы".
Теперь нужно собрать проект воедино. Сначала откомпилируем каждый файл с расширением . с: $ gcc -с print_up.c В результате компиляции должны появиться объектные файлы print_up.o и main.o, которые следует скомпоновать в один бинарный файл: $ gcc -о printup print_up.o main.o
Если компилятор gcc вызывается с опцией -с, но без опции -о, то имя выходного файла получается заменой расширения .с на .о. Например, из файла foo.c получается файл foo.o. Осталось только запустить и протестировать программу: $ ./printup Обратите внимание на то, что заголовочный файл print_up.h не компилируется. Заголовочные файлы вообще никогда отдельно не компилируются. Дело в том, что на стадии препроцессирования (условно первая стадия компиляции) все директивы #include заменяются на содержимое указанных в них файлов.
Related Articles
Set as favorite
Bookmark
Email This
Hits: 584 Комментарии (0)RSS feed CommentsНаписать комментарий |