
- •Лекция 2
- •Базовые элементы языка программирования
- •Категории лексем
- •Идентификаторы
- •Ключевые слова
- •Зарезервированные идентификаторы
- •Стандартные идентификаторы
- •Идентификатор пользователя
- •Константы
- •Литералы
- •Целые константы
- •Вещественные константы
- •Булевские (логические) константы
- •Символьные константы
- •Строковые константы
- •Именованные типизированные константы
- •Перечислимые константы
- •Препроцессорные константы
- •Знаки операций
- •Знаки пунктуации
- •Разделители
- •Пробельные разделители
- •В результате изучения материала лекции необходимо знать
Знаки операций
Знаки операций также являются видом лексем. Они обеспечивают формирование и последующее вычисление выражений, как некоторых правил для получения значений. Один и тот же знак операции может употребляться в различных выражениях и по-разному интерпретироваться в зависимости от контекста. Для изображения операций в большинстве случаев используется несколько символов. Например:
[ ] // операция индексирования
+ - * / % ++ -- // арифметические операции
&& || ! // логические операции И, ИЛИ, НЕ
= += *= -= и т.д. // операции присваивания
== != < <= > >= // операции отношения
~ & | ^ << >> // поразрядные логические операции и операции сдвига
// (отрицание, И, ИЛИ, исключающее ИЛИ, сдвиг влево, сдвиг вправо)
, //операция «запятая», последовательное вычисление
:: //операция изменения области видимости
Полный список операций мы рассмотрим позже.
Знаки пунктуации
Знаки пунктуации представляют определенный вид лексем:
{ } , ; : … #
Фигурные скобки { }
обозначают соответственно начало и конец составного оператора или блока:
if (d > x) { d--; x++; }
используются для выделения списка компонентов в определении типов структур, объединений, классов:
class point { int x, y;
point(int, int);
};
используются при инициализации массивов и структур при их определении:
int a[5] = {1, 2, 3, 4, 5};
Запятая используется как разделитель элементов в списке выражений, параметров или аргументов функции, в описаниях и определениях объектов. Например:
f (a, 7); // скобки представляют список аргументов вызова функции
Точка с запятой завершает каждый оператор, каждое определение функции (кроме определения функции) и каждое описание. Отдельный символ ; считается пустым оператором.
Двоеточие служит для отделения имени производного класса от списка базовых классов при описании производного класса.
Многоточие (три точки без пробелов) используется для обозначения переменного числа параметров у функции при ее определении и описании.
Символ # используется для обозначения директив препроцессора. Директивы препроцессора начинаются со специального знака #, помещаемого в первой позиции строки.
Директивы препроцессора позволяют программисту:
с помощью директивы #define: создавать именованные константы
включать директивой #include в исходный текст программы, поступающий на компиляцию, копию текста из указанного в директиве файла (называемого включаемым или заголовочным) в то место, где находится эта директива. Это повышает мобильность программ: при изменении системы программирования или компьютера приходится менять содержимое только подключаемых файлов. Директива #include имеет следующие форматы:
#include <спецификация файла>
#include “спецификация файла”
Различие между ними заключается в методе поиска препроцессором включаемого файла. Если имя файла заключено в угловые скобки (< и >), то файл будет отыскиваться в «стандартных» директориях, заданных опцией среды. В поставку компиляторов С++ включается некоторое количество заголовочных файлов, каждый из которых поддерживает отдельное семейство программных средств.
Вторая форма директивы отыскивает файл по маршруту, указанному спецификацией файла или в текущем каталоге. Если файл там не найден, просматриваются те же директории, что и в первом случае. Например, при работе с программами, состоящими из нескольких программных файлов, заголовочные файлы могут содержать прототипы функций, объявления и определения классов, структур, объединений, перечислимых типов, общие для этих файлов.
Заголовочные файлы в С традиционно имеют расширение .h. Заголовочные файлы языка С++ вообще не имеют расширения. Некоторые заголовочные файлы языка С были преобразованы в заголовочные файлы языка С++: у них убрали расширение h и добавили префикс с (<math.h> <cmath>; <string.h> <cstring>).
Современный стиль требует использования глобального пространства имен std. При этом директива включения заголовочного файла #include трансформируется. Например, как мы уже отмечали, директива #include <iostream.h> будет заменена на две инструкции:
#include <iostream>
using namespace std;
где iostream уже не является именем файла, а означает просто идентификатор, по которому компилятор находит требуемые файлы.
организовывать условную компиляцию, т.е. в зависимости от заданных в командной строке или среде параметров получать различный программный код. Условная компиляция также помогает повышать мобильность программ. Общий вид секции условной компиляции:
#if логическое_выражение_1
TRUE-секция_1
#else
#elif логическое_выражение_2
TRUE-секция_2
…
#elif логическое_выражение_N
TRUE-секция_N
#else
FALSE-секция
#endif
6*Заголовочный файл может содержать директивы #include, поэтому иногда трудно понять, какие же конкретно заголовочные файлы включены в данный исходный текст, и некоторые заголовочные файлы могут оказаться включенными несколько раз. Избежать этого позволяют условные директивы препроцессора. Рассмотрим пример:
#ifndef BOOK_H
#define BOOK_H
/* содержимое файла book.h */
#endif
Условная директива #ifndef проверяет, не было ли значение BOOK_H определено ранее. (BOOK_H – константа препроцессора) и (если – нет) препроцессор обрабатывает последующие строки вплоть до директивы #endif. В противном случае он пропускает строки от #ifndef до # endif.
Директива #define BOOK_H определяет константу препроцессора BOOK_H. Поместив эту директиву непосредственно после директивы #ifndef, мы можем гарантировать, что содержательная часть заголовочного файла book.h будет включена в исходный текст только один раз, сколько бы раз ни включался в текст сам этот файл.
Распространенным применением условных директив препроцессора является включение в текст программы отладочной информации (#ifdef... #endif) и определение некоторой препроцессорной константы (например, DEBUG). При наличии директивы с определением константы выполняются условные директивы, помещенные в тексте программы, при отсутствии константы (ее определение можно закрыть символом комментария) – нет.
Например:
//#define DEBUG
int main()
{
#ifdef DEBUG
cout << "Начало выполнения main()\n";
#endif
string word;
while ( cin >> word )
{
#ifdef DEBUG
cout << "Прочитано слово: " << word << "\n";
#else ..........
#endif
//………..
}
// ...
return 0;
}