
- •1. Введение
- •2. Элементы языка
- •2.1. Первые программы
- •2.2. Алфавит языка
- •2.3. Комментарии
- •2.4. Типы данных
- •2.5. Целые типы данных
- •2.6. Плавающие типы данных
- •2.7. Константы-строки, или литералы
- •2.8. Директива препроцессора define
- •2.9. Описания
- •2.10. Модификатор const
- •3. Выражения
- •3.1. Операция и выражение присваивания
- •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.2. Двунаправленные и кольцевые списки
- •24.3. Операции над кольцевыми списками
- •25. Стеки
- •25.1. Реализация стека через массив
- •25.2. Реализация стека через динамическую цепочку звеньев
- •26. Двоичные деревья
- •26.1. Определение и построение
- •26.2.Таблицы
- •27. Список литературы
5.6. Указатели и многомерные массивы
Рассмотрим разницу между объектами a и b, описанными следующим образом:
int a[10][10];
int * b[10];
И a и b можно использовать сходным образом в том смысле, что как a[5][5], так и b[5][5] являются обращениями к отдельному значению типа int. Но a - настоящий массив: под него отводится 100 ячеек памяти и для нахождения любого указанного элемента проводятся обычные вычисления с индексами, которые требуют умножения. Для b описание выделяет только 10 указателей. Каждый из них должен быть установлен так, чтобы он указывал на массив целых.
Если предположить, что каждый из них указывает на массив из 10 элементов, то тогда где-то будет отведено 100 ячеек памяти плюс еще 10 ячеек для указателей. Таким образом, массив указателей использует несколько больший объем памяти и может требовать наличие явного шага инициализации. Но при этом возникают 2 преимущества: доступ к элементу осуществляется косвенно через указатель, а не посредством умножения и сложения, и строки массива могут иметь различные длины. Это означает, что каждый элемент b не должен обязательно указывать на вектор из 10 элементов. Эту разницу можно увидеть в следующем примере.
char day [5][12] = {
“понедельник”, // В каждой строке 12 символов.
“вторник”,
“среда”,
“четверг”,
“пятница”
};
Здесь константные указатели day[0], day[1], …, day[4] адресуют участки памяти одинаковой длины 12 байт каждый:
day day +1 day + 2 day + 3 day + 4
|
|
|
|
|
char * day1[2] = { “суббота”, // 7 символов + ‘/0’
“воскресенье”}; // 11 символов + ‘/0’
-
day1[0]
day1[1]
-
с
у
б
б
о
т
а
\0
в
о
с
к
р
е
с
е
н
ь
е
\0
Здесь переменные-указатели day1[0] и day1[1] адресуют участки памяти соответственно в 8 и 12 байт.
6. Операция sizeof
Эта операция выполняется на стадии компиляции. Результатом этой операции является число байтов, необходимое для размещения объекта в памяти. Существует два варианта синтаксиса этой операции. В первом из них единственный операнд операции определяет некоторый тип языка, и он должен быть заключен в скобки:
sizeof ( float )
sizeof ( int )
Во втором операнд задает некоторое выражение и здесь использование скобок необязательно:
sizeof a;
sizeof *ip;
sizeof array[ i ];
Заметим, что при получении размеров массивов, несмотря на то, что имя массива является указателем, результатом операции
sizeof array,
где array - имя некоторого массива, является длина в байтах этого массива. Это свойство можно использовать для вычисления числа элементов в массиве:
const n = 20;
int array [n];
. . .
int num=sizeof array / sizeof(int) // num = = 20.
Результатом операции sizeof над ссылкой является длина типа, с которым сопоставлена ссылка, т.е. sizeof( double & ) и sizeof( double ) эквивалентны.