Раздельная компиляция программ. Продолжительность хранения, область видимости и компоновка. Пространства имен.
// Пример программы, состоящей из трех файлов
//coordin.h — шаблоны структур и прототипы функций
#ifndef COORDIN_H_
#define COORDIN_H_
struct polar
{
double distance; // расстояние от исходной точки
double angle; // направление от исходной точки
};
struct rect
{
double x; // расстояние по горизонтали от исходной точки
double у; // расстояние по вертикали от исходной точки
};
polar rect_to_polar(rect xypos);
void show_polar(polar dapos);
#endif
// file1.срр – головная программа
#include <iostream>
#include "coordin.h" // шаблоны структур, прототипы функций
using namespace std;
int main()
{
rect rplace;
polar pplace;
cout «"Enter the x and у values: "; // ввод значений х и у
while (cin >> rplace.x >> rplace.у) // ловкое использование сіn
{
pplace = rect_to_polar(rplace);
show_polar(pplace);
cout «"Next two numbers (q to quit): "; // ввод следующих двух чисел (q для завершения)
}
cout «"Done.\n";
return 0;
}
// file2.cpp — содержит функции, вызываемые в file1.срр
#include <iostream>
#include <cmath>
#include "coordin.h" // шаблоны структур, прототипы функций
polar rect_to_polar(rect xypos) // Преобразование прямоугольных координат в полярные
{
using namespace std;
polar answer;
answer.distance = sqrt(xypos.x * xypos.x + xypos.у * xypos.у);
answer.angle = atan2(xypos.y, xypos.x);
return answer; // возврат структуры polar
}
// Отображение полярных координат с преобразованием радиан в градусы
void show_polar(polar dapos)
{
using namespace std;
const double Rad_to_deg = 57.29577951;
cout << "distance = " << dapos.distance;
cout «", angle = " «dapos. angle * Rad_to_deg;
cout << " degrees\n";
}
// twofile1.срр — переменные с внешним и внутренним связыванием
#include <iostream> // должен компилироваться вместе с twofile2.cpp
int torn =3; // определение внешней переменной
int dick = 30; // определение внешней переменной
static int harry = 300; // статическая, внутреннее связывание
|
void remote_access(); // Прототип функции
int main()
{
using namespace std;
cout << "main() reports the following addresses:\n"; // вывод адресов
cout << &tom «" = &tom, " «&dick «" = &dick, ";
cout << &harry << " = &harry\n";
remote_access();
return 0;
}
// twofile2.срр — переменные с внутренним и внешним связыванием
#include <iostream>
extern int torn; // переменная torn определена в другом месте
static int dick = 10; // переопределяет внешнюю переменную dick
int harry = 200; // определение внешней переменной, конфликт с harry из twofile1 отсутствует
void remote_access()
{
using namespace std;
cout << "remote_access() reports the following addresses:\n"; // вывод адресов
cout «&tom «" = &tom, " << &dick «" = &dick, ";
cout << &harry << " = &harry\n";
}
// static.срр — использование статической локальной переменной
#include <iostream>
const int ArSize = 10; // Константы
void strcount(const char * str); // Прототип функции
int main()
{
using namespace std;
char input[ArSize];
char next;
cout << "Enter a line: \n";
cin.get(input, ArSize);
while(cin)
{
cin.get(next);
while (next!= '\n') // строка не помещается;
cin.get(next); // избавиться от остатка
strcount (input);
cout «"Enter next line (empty line to quit):\n";
cin.get(input, ArSize);
}
cout «"Bye\n";
return 0;
}
void strcount(const char * str)
{
using namespace std;
static int total = 0; // статическая локальная переменная
int count = 0; // автоматическая локальная переменная
cout «"\”" «str «"\" contains ";
while (*str++) // переход к концу строки
count++;
total += count;
cout «count << " characters\n";
cout << total << " characters total\n";
}
// namesp.h
#include <string>
// Создание пространств имен pers и debts
namespace pers
{
struct Person
{
std::string fname;
std::string lname;
};
void getPerson(Person &);
void showPerson(const Person &);
}
namespace debts
|
{
using namespace pers;
struct Debt
{
Person name;
double amount;
};
void getDebt(Debt &);
void showDebt(const Debt &);
double sumDebts(const Debt ar[], int n);
}
// namesp.cpp -- пространства имен
#include <iostream>
#include "namesp.h"
namespace pers
{
using std::cout;
using std::cin;
void getPerson(Person & rp)
{
cout «"Enter first name: "; // ввод имени
cin » rp.fname;
cout «"Enter last name: "; // ввод фамилии
cin >> rp.lname;
}
void showPerson(const Person & rp)
{
std::cout «rp.lname «", " «rp.fname;
}
}
namespace debts
{
void getDebt(Debt & rd)
{
getPerson(rd.name);
std::cout «"Enter debt: "; // ввод суммы задолженности
std::cin >> rd.amount;
}
void showDebt(const Debt & rd)
{
showPerson(rd.name);
std::cout <<": $" «rd.amount «std::endl;
}
double sumDebts(const Debt ar[], int n)
{
double total = 0;
for (int i = 0; i < n; i++) j
total += ar[i].amount;
return total;
}
}
// usenmsp.срр — использование пространств имен
#include <iostream>
#include "namesp.h"
void other(void);
void another(void);
int main(void)
{
using debts::Debt;.
using debts::showDebt;
Debt golf = {{"Benny", "Goatsniff"}, 120.0 };
showDebt(golf);
other();
another();
return 0;
}
void other(void)
{
using std::cout;
using std::endl;
using namespace debts;
Person dg = {"Doodles", "Glister"};
showPerson(dg);
cout «endl;
Debt zippy[3];
int i;
for (i = 0; i < 3; i ++)
getDebt(zippy[i]);
for (i = 0; i < 3; i++)
showDebt(zippy[i]);
cout «"Total debt: $" «sumDebts (zippy, 3) «endl;
return;
}
void another(void)
{
using pers::Person;
Person collector = { "Milo", "Rightshift" };
pers::showPerson(collector);
std::cout «std::endl;
}
1. Имеется следующий заголовочный файл:
// golf.h
const int Len = 40;
struct golf
{
char fullname[Len];
int handicap;
};
void setgolf(golf & g, const char * name, int he); // Неинтерактивная версия: функция присваивает //структуре.типа golf имя игрока и его гандикап (фору), используя передаваемые ей аргументы
int setgolf(golf & g); // Интерактивная версия: функция предлагает пользователю ввести имя и //гандикап, присваивает элементам структуры g введенные значения; возвращает 1, если введено //имя, и 0, если введена пустая строка
|
void handicap(golf & g, int he); // Функция устанавливает новое значение гандикапа
void showgolf(const golf & g); // Функция отображает содержимое структуры типа golf
Обратите внимание, что функция setgolf() перегружена. Вызов первой версии функции имеет следующий вид:
golf ann
setgolf(ann, "Ann Birdfree", 24);
Функция предоставляет информацию, которая содержится в структуре ann. Вызов второй версии функции имеет следующий вид:
golf andy
setgolf(andy);
Функция предлагает пользователю ввести имя и гандикап, а затем сохраняет эти данные в структуре andy. Постройте многофайловую программу на основе этого заголовочного файла. Один файл по имени golf.cpp должен содержать определения функций, которые соответствуют прототипам заголовочного файла. Второй файл должен содержать функцию main() и обеспечивать реализацию всех средств прототипированных функций. Например, цикл должен запрашивать ввод массива структур типа golf и прекращать ввод после заполнения массива, либо когда вместо имени игрока в гольф пользователь вводит пустую строку. Чтобы получить доступ к структурам типа golf, функция main() должна использовать только прототипированные функции.
Задание на дом
1. Напишите программу, включающую три файла и использующую следующее пространство имен:
namespace SALES
{
const int QUARTERS = 4;
struct Sales
{
double sales[QUARTERS];
double average;
double max;
double min;
}
void setSales (Sales & s, const double ar[], int n); // Копирует меньшее значение из 4 или п //элементов из массива аr в член sales структуры s, вычисляет и сохраняет среднее //арифметическое, максимальное и минимальное значения введенных чисел; оставшиеся //элементы sales, если таковые есть, устанавливаются в 0
void setSales(Sales & s); // Интерактивно подсчитывает продажи за 4 квартала, сохраняет их //в члене sales структуры s, вычисляет и сохраняет среднее арифметическое, а также //максимальное и минимальное значения введенных чисел
void showSales(const Sales & s); // Отображает всю информацию из структуры s
}
Первый файл должен быть заголовочным и содержать пространство имен. Второй файл должен содержать исходный код и расширять пространство имен, предоставляя определения трех прототипированных функций. В третьем файле должны объявляться два объекта Sales. Он должен использовать интерактивную версию функции setSales() для предоставления значений первой структуре и неинтерактивную версию той же функции для предоставления значений второй структуре. Он также должен отображать содержимое обеих структур с помощью функции showSales().