#include
— вставляет текст из указанного файла,#define
— задает макроопределение (макрос) с параметрами или без
(во втором случае это просто символическая константа),#undef
— отменяет предыдущее определение,#ifdef
— осуществляет условную компиляцию при определённости макроса,#ifndef
— осуществляет условную компиляцию при неопределённости макроса,#else
— ветка условной компиляции при ложности выражения.#define FLAG1
#ifdef FLAG1
// Код, помещённый здесь, откомпилируется только,
// если определена макроподстановка FLAG1
#else
// Данный код откомпилируется, если макроподстановка FLAG1 не определена
#endif /* FLAG1 */
Include guards — шаблонная конструкция (клише), вставляемая в заголовочный файл.
#ifndef H_FILE_NAME_HPP
#define H_FILE_NAME_HPP
// Содержимое заголовочного файла
#enfif /* H_FILE_NAME_HPP */
Такая кострукция защищает проект от повторного включения прототипов функции и зацикливания на этапе препроцессирования, что, в свою очередь, приводит к сокращению времени компиляции, а в случае зацикливания к корректной сборке проекта.
В режиме включенных предкомпилированных заголовков при компиляции
заголовочных файлов все они попадают в откомпилированном виде в файл
*.pch
(для Visual Studio), тогда при необходимости повторного
использования они не компилируются заново, а берутся из *.pch
. Это
приводит к уменьшению времени компиляции в больших проектах.
Перечисления, согласно стандарту C++98, объявляются следующим образом:
cpp
enum DayOfWeek {MON, TUE, WED, THU, FRI, SAT, SUN};
Каждый элемент перечисления это целое число: MON = 0
, TUE = 1
, …
При этом существует возможность явно задавать значения элементов enum
.
Например:
enum DayOfWeek {MON, TUE = 3, WED, THU, FRI, SAT, SUN};
Тогда MON = 0
, TUE = 3
, WED = 4
, …
Благодаря тому, что все имена перечисления являются целыми числами возможно следующее присваивание:
int day = MON; // Ok, day == 0;
DayOfWeek dow = 5 // Ошибка компиляции
DayOfWeek wod = static_cast<DayOfWeek>(5);
При объявлении enum
все имена перечисления экспортируются во внешнюю обасть
видимости, это приводит к проблеме коллизии имен в крупных проектах. Для
решения данной проблемы в C++11 был введен enum class
— строго
типизированные перечисления с ограниченной областью видимости. Объявление
enum class
происходит следующим образом:
enum class DayOfWeek {MON, TUE, WED, THU, FRI, SAT = 6, SUN};
При этом особенности работы с ним следующие:
// Ошибка при преобразовании DayOfWeek к int
int day = DayOfWeek::WED;
// Ошибка: WED нет в облати видимости
int wday = WED;
// Присваение переменной значения из множества имен перечисления DayOfWeek
DayOfWeek dow = DayOfWeek::FRI;
// При необходимости присваивания переменной типа DayOfWeek целого числа
// можно воспользоваться оператором static_cast<type>(object);
DayOfWeek sat = static_cast<DayOfWeek>(6);
Часто имена перечислений используются в операторе switch
.
switch (dayOfWeek) {
case DayOfWeek::MON: cout << "Monday\n"; break;
case DayOfWeek::TUE: cout << "Tuesday\n"; break;
case DayOfWeek::WED: cout << "Wedesday\n"; break;
case DayOfWeek::THU: cout << "Thusday\n"; break;
case DayOfWeek::FRI: cout << "Friday\n"; break;
case DayOfWeek::SAT: cout << "Satuday\n"; break;
case DayOfWeek::SUN: cout << "Sunday\n"; break;
}
// Создание массива из 5 элементов типа int
int b[5];
// Создание и инициализация массива из 4 элементов
int a[] = {2, 3, 5, 7};
// Запись в последний элемент масива
a[3] = 1;
// Так нельзя копировать, только в цикле
b = a;
Так как массивы в C/C++ не помнят своего размера, то его необходимо определять вручную след образом:
int size = sizeof(arr2) / sizeof(int);
// sizeof(arr2) возвращает размер массива в байтах
// sizeof(int) возвращает размер элемента массива
int a[] = {3, 7, 9, 5, 7, 2, 7};
for (int x : a) // Доступ к x только на чтение
cout << x;
for (int &x : a) // x передается по ссылке, поэтому
x += 1; // доступ есть на чтение и запись
В C/C++ массив всегда передается по ссылке, поэтому использование
оператора sizeof()
, для определения его размера, бесполезно. Потому при
передаче массива в функцию следует явно передавать и его размер.
const int n = 5;
int a[n] = {1, 3, 5, 6, 1}; // создали массив фиксированной длины 5
// …
void f(int a[], int len) { // создали функцию для работы с массивами
// … // любой заданной длины len
}
// …
f(a, n); // вызвали функцию для нашего массива длины 5