Дополнительные сведения о языке C++
Файлы программы и единицы компиляции
При создании программ на языке C++ следует иметь в виду, что программирование на этом языке опирается на модульный принцип построения программы. Это значит, что программа, которая в результате выглядит как один файл с расширением. exe, во время разработки может состоять из множества файлов с расширением. cpp и.h. Файлы с расширением. cpp называются исходным кодом, а файлы с расширением. h – заголовочными файлами или заголовками. Поскольку каждый файл исходного кода подается на вход компилятора и из него образуется файл промежуточного объектного кода, файлы исходного кода являются единицами компиляци. Процесс создания программы состоит из трех этапов.
1. Работа препроцессора. На этом этапе директивы препроцессора заменяются кодом на языке C++. Чтобы облегчить работу программиста, в исходных кодах существует возможность указывать, какую часть кода надо компилировать, а какую пока не стоит. Есть возможность помещать в исходный код выражения, которые к началу компиляции должны превратиться в константы того или иного типа, есть возможность указывать, что в некое место файла исходного кода должен быть вставлен текст из другого файла. Результатом работы препроцессора является файл, в котором все эти действия выполнены и который можно подавать на вход компилятора.
2. Работа компилятора. Расширенные и преобразованные в соответствии с директивами препроцессора файлы исходного кода подаются на вход компилятора, на выходе которого получаются файлы объектного кода.
3. Работа линковщика. Файлы объектного кода связываются между собой в единый исполняемый файл с расширением. exe.
В общем случае за то, какие именно файлы будут обработаны препроцессором, скомпилированы, а потом собраны в исполняемый файл, отвечает специальная программа управления проектами. В большинстве версий языка С++ эта программа носит название make. На вход программы make подается специальный файл (makefile), в котором описывается состав проекта, опции препроцессора, компилятора и линковщика для каждой единицы компиляции, список доступных каталогов и прочие необходимые сведения. В случае eVC все стадии создания файла программы от работы препроцессора до линковки обычно не видны разработчику. Он лишь выполняет команду Build или Execute из пункта меню Build, и весь процесс выполняется за один шаг. Тем не мене в реальности «за ширмой» среды выполняются все этапы, и в качестве файла конфигурации проекта выступает файл с расширением. vcp.
Препроцессор и заголовочные файлы
Файлы заголовков
Файлы заголовков предназначены для хранения определений, которые одновременно применяются в нескольких единицах компиляции, и для объявления имен, которые должны быть видимы более чем в одном модуле программы. В файлах заголовков также объявляются имена и функции, реализация которых находится в бинарных файлах. Использование заголовочных файлов сокращает размер исходных текстов программы, поскольку в сами файлы исходных текстов вставляются только ссылки на заголовочные файлы (при помощи директивы #include). Эти ссылки заменяются текстом заголовочного файла в процессе работы препроцессора.
Какая информация может быть помещена в файлы заголовков? Строго говоря, разработчик может помещать в эти файлы любую информацию, поскольку сами файлы после работы препроцессора просто вставляются в основной файл на место директивы #include. Список хранящихся в этих файлах данных приведен ниже.
1. Объявления функций, которые могут быть использованы в нескольких модулях.
2. Описания классов.
3. Описания внешних переменных.
4. Определения макросов.
5. Определения типов, доступных для всего проекта.
Использование заголовочных файлов и функционирование препроцессора тесно связаны. Какие же директивы для управления работой препроцессора могут быть включены в исходные файлы и в файлы заголовков? Это показано в следующем примере.
Упражнение 4.7
1. Создать простое приложение и сохранить его с именем AdvancedCPP.
2. На вкладке FileView отыскать файл newres.h и двойным щелчком открыть его в редакторе кода. Поскольку этот файл содержит в себе множество директив препроцессора, он послужит хорошей иллюстрацией к их описанию.
Директива #include задает включение в текст данного файла текста другого файла, имя которого указано после директивы. В файле newres.h есть несколько директив #include.
#include
Выполнение этой инструкции приведет к тому, что перед компиляцией в этом месте в текст файла newres.h будет включен текст файла commctrl.h, но только для подачи на вход компилятору. Текст файла newres.h, хранимый на диске, изменен не будет.
Директива #define используется для создания символических констант, для определения макрофункций и для определения управляющего идентификатора.
3. Найти в редакторе кода следующую строку:#define AFXCE_IDR_SCRATCH_SHMENU 28700