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

Директивы условной компиляции #if, #ifdef и #ifndef применяются для того, чтобы исключить компиляцию отдельных частей программы. Это бывает полезным при отладке или, например, при поддержке нескольких версий программы для различных платформ.

Формат директивы #if:

#if константное_выражение

...

[ #elif константное_выражение

...]

[ #elif константное_выражение

...]

[# else

...]

#endif

Количество директив #elif произвольное. Исключаемые блоки кода могут содержать как описания, так и исполняемые операторы.

Пример

#if 0 //временно закомментирован фрагмент кода

int i, j;

double x,y;

#endif

Директивы #ifdef и #ifndef часто применяются для того, чтобы управлять компиляцией в зависимости от того, определен ли с помощью директивы #define указанный ней символ (хотя бы как пустая строка).

Директива #ifndef часто применяется для того, чтобы обеспечить включение заголовочного файла только один раз (в случае многофайлового проекта возможно образование перекрестных ссылок на заголовочные файлы - это приведет к ошибке компиляции):

#ifndef HEADER_INCLUDED

# include "myheader.h"

#define HEADER_INCLUDED

#endif

Директива #undef

Данная директива удаляет определение символа.

Предопределенные макросы

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

_DATE_ − содержит строку с текущей датой в формате день месяц год.

_FILE_ − содержит строку с полным именем текущего файла.

_LINE_ − текущая строка исходного текста.

_TIME_ − текущее время.

Пример

printf("Текущая дата -%s\n", _DATE_);

 

Области действия и пространства имен

Каждый программный объект имеет область действия, которая определяется видом и местом его объявления. Существуют следующие категории области действия: блок, файл, функция, прототип, класс и поименованная область действия.

Блок. Идентификаторы, описанные внутри блока, являются локальными. Область действия идентификатора начинается в точке определения и заканчивается в конце блока, видимость − в пределах блока и внутренних блоков, время жизни − до конца блока. После выхода из блока память освобождается.

Файл. Идентификаторы, описанные вне любого блока, функции или пространства имен, имеют глобальную видимость и постоянное время жизни.

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

Прототип функции. Идентификаторы, указанные в списке параметров прототипа (объявления функции), имеют областью действия только прототип функции.

Класс. Элементы структур, объединений и классов (за исключением статических элементов) являются видимыми лишь в пределах класса.

Поименованная область. С++ позволяет явным образом задать область определения имен как часть глобальной области с помощью оператора namespace.

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

struct Node {

int Node;

int i;

} Node;

 

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

- имена переменных, функций, типов, определенных пользователем, и констант перечислений в пределах одной области видимости;

- имена типов перечислений, структур, классов и объединений;

- имена элементов каждой структуры, класса и объединения;

- имена меток.

Внешние объявления

Любая функция автоматически видна во всех модулях программы. Если требуется ограничить область действия функции файлом, в котором она описана, используется модификатор static.

Для того чтобы сделать доступной в нескольких модулях переменную или константу, необходимо:

- определить ее в одном модуле как глобальную;

- в других модулях объявить ее как внешнюю с помощью модификатора extern.

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

Пример. Описание двух глобальных переменных в файлах one.cpp и two.cpp с помощью заголовочного файла.

// my_header.h

extern int a;

extern double b;

...

____________

// one.cpp

#include "my_header.h"

int a;

...

____________

// two.cpp

#include "my_header.h"

double b ;

...

____________

Обе переменные видны в файлах one.cpp и two.cpp.

Если переменная описывается как static, область ее действия ограничивается файлом, в котором она описана.

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

Поименованные области

Поименованные области служат для логического группирования объявлений и ограничения доступа к ним. Чем больше программа, тем актуальнее использование поименованных областей. Простейшим примером применения является отделение кода, написанного одним человеком, от кода, написанного другим. При использовании единственной глобальной области видимости формировать программу из отдельных частей очень сложно из-за возможного совпадения и конфликта имен. Использование поименованных областей препятствует доступу к ненужным средствам.

Объявление поименованной области имеет формат:

namespace [имя_области] {/*объявления*/}

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

Если имя области не задано, компилятор определяет его самостоятельно с помощью уникального идентификатора, различного для каждого модуля. Объявление объекта в непоименованной области равнозначно его описанию как глобального с модификатором static. Помещать объявления в такую область полезно для того, чтобы сохранить локальность кода. Нельзя получить доступ из одного файла к элементу неименованной области другого.

Пример

namespace demo {

int i=1;

int k=0;

void func1(int);

void func2(int) {/*...*/}

}

namespace demo { // расширение

// int i=2; // неверно − двойное определение

void func2(int); // повторное объявление

В объявлении поименованной области могут присутствовать как объявления, так и определения. Логично помещать в нее только объявления, а определять их позднее с помощью имени области и оператора доступа к области видимости : :, например:

void demo: :func1(int) {/*...*/}

Объекты, объявленные внутри области, являются видимыми с момента объявления. К ним можно явно обращаться с помощью имени области и оператора доступа к области видимости, например:

demo: : int i=100; demo: : func2(10);

Если имя часто используется вне своего пространства, можно объявить его доступным с помощью оператора using:

using demo: :i;

После этого можно использовать имя без явного задания области.

Если требуется сделать доступными все имена из какой-либо области, используется оператор using namespace:

using namespace demo;

Операторы using и using namespace можно использовать и внутри объявления поименованной области, чтобы сделать в ней доступными объявления из другой области:

namespace dam {

using demo: : i;

...

}

Задание

Собрать разработанные вами функции в модули в соответствии с их назначением (математические функции, функции обрабротки строк и т. д.) и подключить их к основной программе.

 


БИБЛИОГРАФИЧЕСКИЙ СПИСОК

 

1. Павловская Т.А. С / C++. Программирование на языке высокого уровня/ Т.А. Павловская. СПб, 2002.

2. Павловская Т.А. С / C++. Структурное программирование: практикум/ Т.А.Павловская, Ю.А. Щупак. СПб, 2002.

3. Павловская Т.А. С / C++. Объектно-ориентированное программирование: практикум/ Т.А.Павловская, Ю.А.Щупак. СПб, 2002.

4. Культин Н.Б. С++ Builder./ Н.Б.Культин. СПб, 2004.


 

ОГЛАВЛЕНИЕ

 

ВВЕДЕНИЕ.. 3

Функции... 3

Объявление и определение функций.. 3

Глобальные переменные. 5

Возвращаемое значение. 5

Параметры функции.. 6

Передача массивов в качестве параметров. 7

Передача имен функций в качестве параметров. 10

Параметры со значениями по умолчанию... 11

Перегрузка функций.. 11

Правила описания перегруженных функций.. 14

Функции стандартной библиотеки... 15

Функции ввода/вывода. 15

Открытие потока. 15

Ввод/вывод. 16

Закрытие потока. 20

Обработка ошибок. 20

Функции работы со строками и символами.. 22

Математические функции.. 25

Директивы препроцессора... 28

Директива #include. 28

Директива #define. 29

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

Директива #undef. 31

Предопределенные макросы.. 31

Области действия и пространства имен... 31

Внешние объявления. 33

Поименованные области.. 34

БИБЛИОГРАФИЧЕСКИЙ СПИСОК.. 37

 

 


 

 

ПРОГРАММИРОВАНИЕ НА ЯЗЫКЕ С++