- •1. Введение
- •2. Элементы языка
- •2.1. Первые программы
- •2.2. Алфавит языка
- •2.3. Комментарии
- •2.4. Типы данных
- •2.5. Целые типы данных
- •2.8. Директива препроцессора define
- •2.9. Описания
- •2.10. Модификатор const
- •3. Выражения
- •3.1. Операция и выражение присваивания
- •2.6. Плавающие типы данных
- •2.7. Константы-строки, или литералы
- •3.2. Арифметические операции
- •3.3. Операции отношения
- •3.4. Логические операции
- •3.5. Побитовые операции
- •3.6. Сдвиги
- •?????3.8. Тернарная или условная операция
- •3.9. Операция следования
- •3.10. Приоритеты операций и порядок вычисления
- •4.6. Оператор выбора switch
- •4.7. Оператор цикла while
- •4.8. Цикл с постусловием do-while
- •4.9. Оператор for
- •4.10. Оператор безусловного перехода
- •4.11. Оператор break
- •4.12. Оператор continue
- •4.13. Оператор return
- •5. Указатели
- •5.1. Определение указателей
- •5.2. Указатели и массивы
- •5.3. Адресная арифметика
- •5.4. Символьные массивы и строки
- •5.5. Многомерные массивы
- •5.6. Указатели и многомерные массивы
- •6. Операция sizeof
- •7. Операции для работы с динамической памятью
- •7.1. Операция выделения памяти new
- •7.2. Операция освобождения памяти delete
- •8. Функции
- •8.1. Определение и вызов функции
- •8.2. Функции. Передача аргументов
- •8.3. Передача многомерных массивов
- •8.4. Указатели на функции
- •8.5. Ссылки
- •8.6. Ссылки в качестве параметров функций
- •8.7. Аргументы по умолчанию
- •8.8. Переопределение функций
- •8.9. Шаблоны функций
- •9. Объявления и определения
- •10. Область существования имени
- •11. Область видимости
- •Здесь будет напечатано
- •12. Классы памяти
- •13. Объявления объектов и типов
- •14. Имена типов
- •15. Синоним имени типа
- •16. Правила преобразования стандартных типов
- •16.1. Явные преобразования
- •16.2. Неявные преобразования стандартных базовых типов
- •16.3. Преобразование производных стандартных типов
- •17. Перечисления
- •18. Классы
- •18.1. Объявление классов
- •18.2. Конструкторы
- •18.3. Деструкторы
- •18.4. Статические члены класса
- •18.5. Указатель this
- •18.6. Статические функции-члены
- •18.7. Указатели на члены класса
- •18.8. Инициализация данных–членов класса
- •18.9. Конструктор копирования и операция присваивания
- •18.10. Дружественные функции
- •18.11. Конструктор и операция new
- •18.12. Вызов деструктора
- •19. Производные классы
- •19.1. Построение производного класса
- •19.2. Защищенные члены класса
- •19.3. Управление уровнем доступа к членам класса
- •19.4. Последовательность вызова конструктора и деструктора при построении производного класса на основе одного базового
- •19.5. Преобразования типов
- •20. Полиморфизм
- •20.1. Раннее и позднее связывание
- •20.2. Виртуальные функции
- •20.3. Абстрактные классы
- •21. Переопределение стандартных операций
- •21.1. Основные определения и свойства
- •21.2. Операции new и delete при работе с абстрактными типами
- •21.3. Использование new при создании динамического объекта абстрактного типа
- •21.4. Операция delete
- •21.5. Преобразование типов
- •22. Некоторые особенности переопределенных операций
- •22.2. Операция [ ]
- •23. Классы и шаблоны
- •24. Списки
- •24.1. Операции над односвязными списками
- •24.3. Операции над кольцевыми списками
- •24.2. Двунаправленные и кольцевые списки
- •25. Стеки
- •25.1. Реализация стека через массив
- •25.2. Реализация стека через динамическую цепочку звеньев
- •26. Двоичные деревья
- •26.1. Определение и построение
- •26.2.Таблицы
- •27. Список литературы
9. Объявления и определения
Любое имя, за исключением имён меток, должно быть объявлено в программе:
int i, j;
double d=7.3;
extern int m;
typedef unsigned int size_t;
int add (int a, int b){ return a+b;}
void func (char*, int);
После этих объявлений компилятор знает, что i, j, m – имена переменных типа int, d – имя переменного типа double, size_t – имя типа, а add и func – имена функций.
В объявлении с именем может сопоставляться не только некоторый тип. С именем может быть сопоставлен некоторый элемент, идентификатором которого оно является. Например, при объявлении int i, j; для переменных i, j отводится память, с этими именами сопоставляются участки памяти по 2 байта, которые можно использовать для хранения значений переменных. С именем size_t сопоставлено имя конкретного типа (unsigned int), синонимом которого является теперь size_t; с именем add сопоставлен код функции. Все такие объявления называют определениями. Однако не все объявления являются определениями. Из всех вышеприведённых объявлений два не являются определениями:
extern int m;
void func (char *, int);
В первом из этих объявлений сообщается только, что переменная m имеет тип int, память же для неё должна выделяться где-то в другом месте, о чём говорит ключевое слово extern.
Второе объявление говорит, что func есть имя функции с двумя аргументами, первый из которых – указатель на char, а второй – int, а сама функция не возвращает никакого значения. Такое объявление называют прототипом функции. Сама же функция func должна быть определена вместе со своим телом где-то в другом месте.
В программе для каждого имени должно присутствовать одно и только одно определение, в то время как объявлений, не являющихся определениями, может быть как угодно много.
10. Область существования имени
После объявления имя можно использовать. Однако оно, как правило, может быть использовано только в некоторой части программы, которая называется областью существования имени.
Текст программы можно разместить в одном файле, а можно и в нескольких различных файлах, каждый из которых содержит целиком одну или несколько функций. Для объединения в одну программу эти файлы компилируются совместно. Информация обо всех этих файлах помещается в так называемый файл проекта (с расширением .prj). Компилятор для каждого исходного файла создаёт объектный код (файл с расширением .obj). Затем все объектные файлы (вместе с библиотечными) объединяются компоновщиком в исполняемый, или загрузочный модуль, который имеет имя файла проекта и расширение .ехе. Область существования имени нужна компилятору для того, чтобы сгенерировать верный машинный код.
Можно выделит 5 видов областей существования имени.
Область существования БЛОК. Блок – это фрагмент программы, заключённый в фигурные скобки { }, например
if (a != 5) {
int j=0;
double k = 3.5;
a++;
…
}
Заметим, что тело любой функции является блоком.
Имя, объявленное в блоке, может быть использовано от точки, где находится его объявление, и до конца блока. Такую же область существования имеют и имена в определении функции:
int f1 (int i){ return i; }
Имя i имеет область существования «блок». Область существования «блок» распространяется и на вложенные блоки.
Область существования ФУНКЦИЯ. Эту область существования имеют только имена меток перехода, используемые оператором goto:
void f (){….
…
goto lab;
…
{… lab: ...}
…
}
Область существования ПРОТОТИП ФУНКЦИИ. Прототип функции есть объявление функции, не являющееся её определением и имеющий, например, вид:
int F(int a, double b, char* str);
Область существования «прототип» заключена между открывающей и закрывающей круглыми скобками. Иначе говоря, имена a, b, str в примере определены только внутри круглых скобок. Из этого следует, что в прототипах можно использовать для аргументов любые имена или не использовать их совсем:
int F(int, double, char*);
Область существования ФАЙЛ. Область существования «файл» имеют имена, объявленные вне любого блока и класса. Такие имена называют глобальными. Глобальные имена определены от точки их объявления и до конца файла, где встретилось их объявление. Примером таких имён являются имена функций.
#include <iostream.h>
int a, b, c[40]; // Глобальные имена;
int f1() // локальное имя f1;
{int i; // локальное имя;
…
}
int count; // глобальное имя;
void f2() { … } // глобальное имя f2.
Область существования КЛАСС.
Такую область существования имеют имена, объявленные в классах. Эти имена определены во всем классе, в котором они объявлены, независимо от точки их объявления.
