Бьерн Страуструп - Язык программирования С++. Главы 2-4 - Описания
ОГЛАВЛЕНИЕ
Страница 3 из 69
2.1 ОПИСАНИЯ
Имя (идентификатор) следует описать прежде, чем оно будет использоваться в программе на С++. Это означает, что нужно указать его тип, чтобы транслятор знал, к какого вида объектам относится имя. Ниже приведены несколько примеров, иллюстрирующих все разнообразие описаний:char ch;Из этих примеров видно, что роль описаний не сводится лишь к привязке типа к имени. Большинство указанных описаний одновременно являются определениями, т.е. они создают объект, на который ссылается имя.
int count = 1;
char* name = "Njal";
struct complex { float re, im; };
complex cvar;
extern complex sqrt(complex);
extern int error_number;
typedef complex point;
float real(complex* p) { return p->re; };
const double pi = 3.1415926535897932385;
struct user;
template<class T> abs(T a) { return a<0 ? -a : a; }
enum beer { Carlsberg, Tuborg, Thor };
Для ch, count, name и cvar таким объектом является элемент памяти соответствующего размера. Этот элемент будет использоваться как переменная, и говорят, что для него отведена память. Для real подобным объектом будет заданная функция.
Для константы pi объектом будет число 3.1415926535897932385. Для complex объектом будет новый тип. Для point объектом является тип complex, поэтому point становится синонимом complex. Следующие описания уже не являются определениями:
extern complex sqrt(complex);Это означает, что объекты, введенные ими, должны быть определены где-то в другом месте программы. Тело функции sqrt должно быть указано в каком-то другом описании. Память для переменной error_number типа
extern int error_number;
struct user;
int должна выделяться в результате другого описания error_number. Должно быть и какое-то другое описание типа user, из которого можно понять, что это за тип. В программе на языке С++ должно быть только одно определение каждого имени, но описаний может быть много. Однако все описания должны быть согласованы по типу вводимого в них объекта.
Поэтому в приведенном ниже фрагменте содержатся две ошибки:
int count;Зато в следующем фрагменте нет ни одной ошибки (об использовании extern см. #4.2):
int count; // ошибка: переопределение
extern int error_number;
extern short error_number; // ошибка: несоответствие типов
extern int error_number;В некоторых описаниях указываются "значения" объектов, которые они определяют:
extern int error_number;
struct complex { float re, im; };Для типов, функций и констант "значение" остается неизменным; для данных, не являющихся константами, начальное значение может впоследствии изменяться:
typedef complex point;
float real(complex* p) { return p->re };
const double pi = 3.1415926535897932385;
int count = 1;Из всех определений только следующее не задает значения:
char* name = "Bjarne";
//...
count = 2;
name = "Marian";
char ch;Всякое описание, которое задает значение, является определением.