Темы лекции
Разбиение программы на модули (файлы)
Структура модуля
Использование функций
Заголовок модуля
Реализация модуля
Подключение модулей
Частные случаи модулей
Как организуется модуль на языке C++?
Как организуется модуль на языке C++?
Заголовочные файлы
Препроцессор
Препроцессор
Синтаксис подключения заголовочных файлов:
Макросы
Заголовочные файлы
Директивы условной компиляции
Директивы условной компиляции
Директивы условной компиляции
Директивы условной компиляции
Как происходит сборка программы?
Как происходит сборка программы?
Как происходит сборка программы?
Что при сборке происходит с библиотечными функциями?
Использование условной компиляции
Что такое #ifndef-#define- #endif?
Заголовочные файлы
Заголовочные файлы
Компиляция и компоновка
278.69K
Category: programmingprogramming

Сборка программ для АСУб и ЭВМб. Тема 3-5

1.

Тема 3-5.
Сборка программ
для АСУб и ЭВМб

2. Темы лекции

• Процесс компиляции и сборки
программы
• Файлы *.cpp и *.h.
• Директивы препроцессора.
• Сборка проекта из нескольких файлов
• Макропроцессор на примере М4.
• Создание диалекта

3.

• Для объявления глобальной
переменной, внешней к данной единице
трансляции, либо внутри функции
используется ключевое
слово extern (чтобы это объявление не
было понято компилятором как
определение локальной переменной).

4. Разбиение программы на модули (файлы)

Самые простые программы могут состоять
из одной функции main
Чуть более сложные включают в себя
другие функции
По мере возрастания сложности программы
функций становится слишком много, в них
становится тяжело ориентироваться
Выход – разбиение функций на отдельные
модули по смысловому значению

5. Структура модуля

Две основные части:
интерфейс (заголовок модуля – файл .h);
реализация (реализация модуля файл .сpp).

6. Использование функций

7. Заголовок модуля

Заголовок модуля – интерфейсная часть,
представленная в виде файла с
расширением .h.
Основное содержание:
описание внешних типов данных;
описание внешних переменных и констант;
описание прототипов внешних функций.

8. Реализация модуля

Реализация модуля – файл с расширением .cpp
Основное содержание:
описание внутренних типов данных;
описание внутренних и внешних переменных и
констант;
реализация внешних и внутренних функций.

9. Подключение модулей

Подключение модуля в программу осуществляется
двумя действиями:
подключение файла заголовка модуля с помощью
директивы #include;
подключение файла текста программы модуля в
проект.

10. Частные случаи модулей

1.
Модуль
содержит
только
часть
реализацию: единственный модуль в
программе, содержащий только функцию main.
2.
Модуль содержит только часть заголовок: в
модуле производится
описание
глобальных типов данных.

11. Как организуется модуль на языке C++?

Модуль логически состоит из двух файлов файла с исходным кодом (source file) и
заголовочного файла (header file)
файл с исходным кодом (module.cpp) включает в
себя определения функций, а также определения
глобальных переменных и констант (если они
есть); в первой строке обычно подключается
заголовочный файл того же модуля:
#include "module.h"
заголовочный файл (module.h) включает в себя
прототипы функций, определения констант,
объявления глобальных переменных - но только
для тех элементов модуля, о которых должны
знать другие модули

12. Как организуется модуль на языке C++?

Если какой-либо модуль использует данный,
необходимо подключить его заголовочный
файл (в двойных кавычках – это указывает
на то, что заголовочный файл не системный,
а собственный):
#include "module.h"
Главный модуль программы обычно
содержит только функцию main и не имеет
заголовочного файла (поскольку функция
main не используется в других модулях)
Некоторые модули включают только
заголовочный файл – например, содержащий
определения глобальных констант

13. Заголовочные файлы

#include <iostream>
int main()
{
using namespace std;
cout<<"Hello, world!"<<endl;
return 0;
}

14. Препроцессор

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

15. Препроцессор

Препроцессор изменяет исходный текст программы:
Удаляет комментарии и выполняет директивы
препроцессора, которыми являются строки программы,
начинающиеся знаком #.
Как правило, препроцессор встроен в компилятор, но
существуют и автономные препроцессоры, с помощью
которых можно получить файл, обработанный
препроцессором.
Препроцессор не относится к языку
программирования, его назначение состоит в обработке
исходного текста программы, поэтому препроцессорные
лексемы не совпадают с рассмотренными ранее
лексемами языка C++.

16.

Директива препроцессора – это инструкция,
которая включает в текст программы файл,
содержащий описание множества функций, что
позволяет правильно компилировать программу.
Это важно
• все директивы препроцессора начинаются со
знака #;
• после директивы препроцессора точка с
запятой не ставится.

17. Синтаксис подключения заголовочных файлов:

Директива #include позволяет включать в текст программы
указанный файл.
Имя файла может быть указано двумя способами:
#include <some_file.h>
#include "my_file.h”
•Если
файл является стандартной библиотекой и
находится в папке компилятора, он заключается в угловые
скобки <>.
•Если файл находится в текущем каталоге проекта, он
указывается в кавычках "".

18. Макросы

Макросом или макроопределением
называется идентификатор, связанный
директивой #define с лексемой или
последовательностью лексем
#define МАКРОС ЗНАЧЕНИЕ
#define M_E 2.71828182845904523536
#define M_PI 3.14159265358979323846

19.

20. Заголовочные файлы

#include <iostream>
int main()
{
using namespace std;
cout<<"Hello, world!"<<endl;
return 0;
}

21. Директивы условной компиляции

1
#if условие
операторы
#endif
2
#if условие
операторы 1
#else
операторы 2
#endif
3
#if условие1
операторы 1
#elif условие2
операторы 2
#endif
4
#if условие1
операторы 1
#elif условие2
операторы 2
#else
операторы 3
#endif

22. Директивы условной компиляции

Примеры:
#define A 5
#if A>10
puts(“Message 1”);
#else
puts(“Message 2”);
#endif
#define A 2
#if A==1
puts("A=1!");
#elif A==2
puts("A=2!");
#else
puts("uncknown A!");
#endif

23. Директивы условной компиляции

#ifndef идентификатор

#endif
#ifdef идентификатор

#endif

24. Директивы условной компиляции

Примеры:
#define DEBUG_MODE

#ifdef DEBUG_MODE
puts(“Режим отладки”);
#endif
#define TEST_MODE
int main(int argc, char *argv[])
{
#ifdef TEST_MODE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int val;
scanf("%d",&val);
printf("%d",val);
return 0;
}

25. Как происходит сборка программы?

Сборка (build) состоит из 3 основных этапов:
на этапе препроцессинга (preprocessing)
директивы препроцессора (например, #include)
заменяются содержимым указанного в них
заголовочного файла, в результате файл с
исходным кодом дополняется прототипами
указанных там функций и объявлениями
глобальных переменных – за счет этого в файле
можно вызывать указанные функции (прототип
впереди) и использовать глобальные
переменные (объявление впереди).
Препроцессор может создавать на диске
временные файлы, которые, однако, удаляются
после окончания сборки

26. Как происходит сборка программы?

Сборка (build) состоит из 3 основных
этапов:
на этапе компиляции (compiling) для каждого
исходного файла составляются таблицы
определенных в нем функций и глобальных
переменных, все определенные функции
переводятся на машинный язык (при переводе
на машинный язык могут выявляться ошибки
компиляции). Результатом работы компилятора
являются файлы module.obj (объектные
файлы) для каждого использованного в
программе модуля

27. Как происходит сборка программы?

Сборка (build) состоит из 3 основных этапов:
на этапе связывания (linking) происходит
привязка всех используемых (вызванных)
функций и глобальных переменных к той
таблице, в которой они определены;
если определения не обнаружены ни в одной
таблице, происходит ошибка связывания
(unresolved external symbol …).
Результатом связывания является файл
program.exe – исполняемый файл

28. Что при сборке происходит с библиотечными функциями?

Прототипы функций находятся в заголовочных
файлах (iostream, math.h, stdio.h, string.h и т.п.)
Объектные файлы с уже переведенными на
машинный язык определениями функций заранее
собраны в библиотеки (файлы с расширением lib
или dll)
определения из статических библиотек
(расширение lib) на этапе связывания
добавляются в исполняемый файл программы
определения из динамических библиотек
(расширение dll) в исполняемый файл не
добавляются; вместо этого в ссылке на
соответствующую функцию указывается, что она
находится в динамической библиотеке, и при ее
вызове происходит обращение к библиотеке
поэтому, статические библиотеки нужны только
на этапе связывания, а динамические – и на
этапе исполнения программы

29. Использование условной компиляции

При многократном подключении модуля необходимо
организовать однократность его компиляции. Это
осуществляется с использованием директив
условной компиляции в файле заголовка модуля в
формате:
#ifndef имя_модуля
#define имя_модуля
… текст заголовка модуля …
#endif
ИЛИ
#pragma once

30. Что такое #ifndef-#define- #endif?

Что такое #ifndef-#define#endif?
Это, как и #include, директивы препроцессора
Директива #define позволяет определить
переменную препроцессора (например, ADD_H)
Директива #ifndef позволяет выяснить,
определена ли переменная препроцессора.
Если она не определена, участок кода до
директивы
#endif вставляется в программу, если же
определена – выбрасывается из нее
Нужны эти скобки для того, чтобы текст
заголовочного файла не мог вставиться в
исходный файл дважды

31. Заголовочные файлы

Файл add.h
#ifndef ADD_H
#define ADD_H
int add(int x, int y);
Файл add.cpp
int add(int x, int y)
{
return x + y;
}
#endif
Файл main.cpp
#include <iostream>
#include “add.h”
int main()
{
using namespace std;
cout<<"The sum of 3 and 4 is: "<<add(3, 4)<<endl;
return 0;
}

32. Заголовочные файлы

33. Компиляция и компоновка

English     Русский Rules