При разработке достаточно больших программ бывает удобным разрабатывать программу не в виде одного файла, а в виде нескольких. В отдельном файле сохраняем функцию 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 далее не обрабатывается. Такой подход позволяет избегать многократного и тем более циклического подключения заголовочных файлов.
|
|
|