Читаем Программирование полностью

typedef int* Pint;                 // Pint — это указатель на int

namespace Long_library_name { /* ... */ }

namespace Lib = Long_library_name; // Lib — это Long_library_name

int x = 7;

int& r = x; // r — это x


Ссылки (см. разделы 8.5.5 и A.8.3) — это механизм указания на объекты, работающий на этапе выполнения программы. Ключевые слова typedef (см. разделы 20.5 и 27.3.1) и namespace относятся к механизмам ссылок на имена, работающим на этапе компиляции. В частности, инструкция typedef не вводит новый тип, а просто задает новое имя существующего типа. Рассмотрим пример.


typedef char* Pchar; // Pchar — это имя типа char*

Pchar p = "Idefix";  // OK: p — это указатель типа char*

char* q = p;         // OK: p и q — указатели типа char

int x = strlen(p);   // OK: p — указатель типа char* 

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

Каждая реализация языка C++ содержит препроцессор (preprocessor). В принципе препроцессор работает до компилятора и преобразовывает исходный код, написанный нами, в то, что видит компилятор. В действительности это действие интегрировано в компиляторе и не представляет интереса, за исключением того, что оно может вызывать проблемы. Каждая строка, начинающаяся символом #, представляет собой директиву препроцессора.

A.17.1. Директива #include

Мы широко использовали препроцессор для включения заголовочных файлов. Рассмотрим пример.


#include "file.h"


Эта директива приказывает препроцессору включить содержимое файла file.h в точку исходного текста, где стоит сама директива. Для стандартных заголовков используются угловые скобки (<...>), а не кавычки ("..."). Например:


#include


Это рекомендованная система обозначений для включения стандартных заголовков. 

A.17.2. Директива #define

Препроцессор выполняет также определенные манипуляции с символами, которые называются макроподстановками (macro substitution). Например, определим имя символьной строки.


#define FOO bar


Теперь везде, где препроцессор увидит символы FOO, они будут заменены символами bar.


int FOO = 7;

int FOOL = 9;


В таком случае компилятор увидит следующий текст:


int bar = 7;

int FOOL = 9;


Обратите внимание на то, что препроцессор знает об именах языка С++ достаточно много, чтобы не заменить символы FOO, являющиеся частью слова FOOL.

С помощью директивы define можно также определить макросы, принимающие параметры.


#define MAX(x,y) (((x)>(y))?(x) : (y))


Их можно использовать следующим образом:


int xx = MAX(FOO+1,7);

int yy = MAX(++xx,9);


Эти выражения будут развернуты так:


int xx = (((bar+1)>( 7))?(bar+1) : (7));

int yy = (((++xx)>( 9))?(++xx) : (9));


Подчеркнем, что скобки необходимы для того, чтобы получить правильный результат при вычислении выражения FOO+1. Кроме того, переменная xx была инкрементирована дважды совершенно неочевидным образом. Макросы чрезвычайно популярны, в основном потому, что программисты на языке С имели мало альтернатив. Обычные заголовочные файлы содержат определения тысяч макросов. Будьте осторожны!

Если уж вам приходится использовать макросы, то называйте их, используя только прописные буквы, например ALL_CAPITAL_LETTERS, а обычные имена не должны состоять только из прописных букв. Прислушайтесь к хорошему совету. Например, в одном из вполне авторитетных заголовочных файлов мы нашли макрос max.

См. также раздел 27.8.

Приложение Б

Обзор стандартной библиотеки

“По возможности, вся сложность должна быть скрыта

от постороннего взгляда”.

Дэвид Дж. Уилер (David J. Wheeler)


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

Б.1. Обзор

Перейти на страницу:
Нет соединения с сервером, попробуйте зайти чуть позже