Многофайловые программы

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

Что это даёт? Подпрограмма, сохранённая в отдельном файле, может быть очень легко использована в другой программе. Достаточно будет только подключить к проекту новой программы файл с этой подпрограммой.

Рассмотрим процесс разработки многофайловой программы. Пример рассмотрим предельно простой — важна техника разработки, а не сложность алгоритма.

Задача 1. Разработать программу для вычисления гипотенузы прямоугольного треугольника. В виде функции оформим само вычисление гипотенузы, и эта функция будет хранится в отдельном файле.

Создадим новый проект (Консольное приложение), например, с таким названием: Many_Files. После создания проекта в папке проекта будет только один файл с расширением cpp. Это файл main.cpp.

Теперь добавим в проект файл для вычисления гипотенузы. Для этого на панели инструментов нажмём на кнопку New file и выберем пункт Empty file (Пустой файл) (либо нажимаем пункт основного меню File/New/Empty file). В открывшемся окне диалога Add file to project (Добавить файл в проект) нажимаем кнопку Да. В появившемся окне Save file (Сохранить файл) задаём имя файла Gipotenuza.cpp и нажимаем на кнопку Сохранить. В следующем окне Multiple selection также нажмём на кнопку OK.

Всё. Теперь в проекте имеется два файла с исходным текстом на языке C++. Остаётся только набрать необходимые тексты и отладить программу.

Текст файла main.cpp:

#include <iostream>

using namespace std;

double Gipotenuza(double a, double b);

int main()

{

   double a, b, c;

   cout << "a, b: ";

   cin >> a>> b;

   c = Gipotenuza(a, b);

   cout << "c=" << c << endl;

   return 0;

}

Текст файла Gipotenuza.cpp:

#include <cmath>

double Gipotenuza(double a, double b)

{

   double c;

   c = sqrt(a*a + b*b);

   return c;

}

Результаты работы:

a, b: 3 4

c=5

Пояснения к тексту программы.

1)В файле main.cpp записан прототип функции, находящейся в другом файле:

double Gipotenuza(double a, double b);

Это надо делать обязательно, так как иначе компилятор ничего не будет знать о функции Gipotenuza() при её вызове в функции main().

2)В файле Gipotenuza.cpp подключен заголовочный файл

#include <cmath>

Он необходим для работы с математической функцией sqrt().

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

Добавление в проект существующего файла

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

Текст файла rus.cpp:

#include <windows.h>

char bufer[256];

char* rus(char *s)

{

   CharToOem(s, bufer);

   return bufer;

}

Делается все просто. Выбираем пункт меню Project/Add files... и в открывшемся окне выделяем нужный файл rus.cpp. Затем нажимаем кнопку Открыть (если файл находится в папке проекта, то он будет виден в окне диалога, если файл лежит в какой-то другой папке, то по дереву каталогов необходимо перейти в папку, где находится этот файл). В следующем окне Multiple selection нажмём на кнопку OK. И всё. Файл включён в проект. Остаётся его использовать. Можно, к примеру, в функции main() выводить необходимые текстовые подсказки на русском языке.

Текст изменённого файла main.cpp:

#include <iostream>

using namespace std;

double Gipotenuza(double a, double b);

char* rus(char *s);

int main()

{

   double a, b, c;

   cout << rus("Катеты a и b: ");

   cin >> a >> b;

   c = Gipotenuza(a, b);

   cout << rus("Гипотенуза c=") << c << endl;

   return 0;

}

Результаты работы:

Катеты a и b: 3 4

Гипотенуза c=5

Использование своих заголовочных файлов в многофайловых программах

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

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

Функции для ввода-вывода поместим в отдельный файл my.cpp, определение структуры и прототипы функции, а также стандартные заголовочные файлы — в заголовочный файл My_Struct.h. Подключим заголовочный файл к основной программе и к файлу с функциями.

Тексты трёх файлов программы:

//Текст файла main.cpp

//--------------------

#include "My_Struct.h"

int main()

{

   Fio x;

   vvod(x);

   print(x);

   return 0;

}


//Текст файла my.cpp

//------------------

#include "My_Struct.h"

void vvod(Fio &x)

{

   cout << "f="; cin >> x.f;

   cout << "n="; cin >> x.n;

   cout << "o="; cin >> x.o;

}

void print(Fio x)

{

   cout << x.f <<" "<< x.n <<" " << x.o << endl;

}


//Текст файла My_Struct.h

//-----------------------

#ifndef MY_STRUCT

#define MY_STRUCT

#include <iostream>

using namespace std;

const int N=15;

struct Fio

{

   char f[N];

   char n[N];

   char o[N];

};

void vvod(Fio &x);

void print(Fio x);

#endif



Результаты работы:

f=Иванов

n=Иван

o=Иванович

Иванов Иван Иванович



Пояснения. В заголовочном файле использована удобная конструкция:

#ifndef MY_STRUCT

#define MY_STRUCT

….................

#endif

Мы не просто объявляем в этом файле какие-то типы, прототипы и т. д., но и делаем это с проверкой:

#ifndef MY_STRUCT — если не объявлена константа MY_STRUCT

#define MY_STRUCT — объявляем её и продолжаем обрабатывать заголовочный файл до конца блока проверки

#endif — конец блока проверки

Если константа MY_STRUCT была ранее объявлена, то файл после первой строки с директивой #ifndef далее не обрабатывается. Такой подход позволяет избегать многократного и тем более циклического подключения заголовочных файлов.

Назад
На верх
Вперёд
Hosted by uCoz