Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Data Structures and Algorithms in C++ 2e (На ру...docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
2.37 Mб
Скачать

XXII Содержание

13.3.5 Поиск типа «сначала вширь»...

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

623

13.4 Направленные графы.........

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

626

13.4.1 Пересечение диграфа...

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

628

13.4.2 Переходное закрытие.....

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

630

13.4.3 Направленные нециклические графы..

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

633

13.5 Кратчайшие пути..........

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

637

13.5.1 Взвешенные графы.....

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

637

13.5.2 Алгоритм Дейкстры....

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

639

13.6 Минимальные деревья охвата....

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

645

13.6.1 Алгоритм Краскэла....

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

647

13.6.2 Чопорный-Jarn'k алгоритм ı

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

651

13.7 Упражнения.............

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

654

14 управлений памятью и B-деревья

665

14.1 Управление памятью......

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

666

14.1.1 Распределение памяти в C ++

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

669

14.1.2 Сборка мусора....

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

671

14.2 Внешняя память и кэширование.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

673

14.2.1 Иерархия памяти..

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

673

14.2.2 Кэширование стратегий....

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

674

14.3 Внешний поиск и B-деревья

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

679

14.3.1 (a, b) Деревья........

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

680

14.3.2 B-деревья..........

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

682

14.4 Сортировка внешней памяти....

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

683

14.4.1 Многоканальное слияние....

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

684

14.5 Упражнения.............

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

685

Полезные математические факты

689

Библиография

697

Индекс

702

Глава

1

C ++ учебник для начинающих

Содержание

1.1

Основной C ++ программирование элементов.......

.

.

.

.

2

1.1.1 Простой C ++ программа...........

.

.

.

..

2

1.1.2 Фундаментальные типы.............

.

.

.

..

4

1.1.3 Указатели, множества и структуры......

.

.

.

..

7

1.1.4 Названные константы, объем и Namespaces

.

.

.

..

13

1.2

Выражения....................

.

.

.

.

16

1.2.1 Изменение типов через кастинг......

.

.

.

..

20

1.3

Поток контроля...................

.

.

.

.

23

1.4

Функции.....................

.

.

.

.

26

1.4.1 Передача параметров..............

.

.

.

..

28

1.4.2 Overloading и Inlining..........

.

.

.

..

30

1.5

Классы......................

.

.

.

.

32

1.5.1 Структура класса...............

.

.

.

..

33

1.5.2 Конструкторы и печи для сжигания отходов производства........

.

.

.

..

37

1.5.3 Классы и распределение памяти.......

.

.

.

..

40

1.5.4 Друзья класса и участники класса......

.

.

.

..

43

1.5.5 Стандартная библиотека шаблона.......

.

.

.

..

45

1.6

C ++ программа и организация файла......

.

.

.

.

47

1.6.1 Программа в качестве примера............

.

.

.

..

48

1.7

Написание C ++ программа.............

.

.

.

.

53

1.7.1 Дизайн....................

.

.

.

..

54

1.7.2 Псевдокодекс................

.

.

.

..

54

1.7.3 Кодирование....................

.

.

.

..

55

1.7.4 Тестирование и отладка...........

.

.

.

..

57

1.8

Упражнения.....................

.

.

.

.

60

2 Глава 1. C ++ учебник для начинающих

1.1 Основной C ++ программирование элементов

Строительство структур данных и алгоритмов требует общающихся инструкций к компьютеру, и превосходный способ выполнить такую коммуникацию использует компьютерный язык высокого уровня, такой как C ++. C ++ развитый из программной LAN - guage C, и, в течение долгого времени, подвергался дальнейшему развитию и развитию из его оригинального определения. Это включило много особенностей, которые не были частью C, такого как символические константы, действующая замена функции, справочные типы, paramet-ric полиморфизм через шаблоны и исключения (которые обсуждены позже). В результате C ++ вырос, чтобы быть сложным языком программирования. К счастью, мы не должны знать каждую деталь этого сложного языка, чтобы использовать его эффективно.

В этой главе и следующем, мы представляем быстрый тур по C ++ язык программирования и его особенности. Было бы невозможно представить полное представление языка в этом коротком периоде, как бы то ни было. Так как мы предполагаем, что читатель уже знаком с программированием с некоторым другим языком, таков как C или Ява, наши описания коротки. Эта глава представляет основные характеристики языка, и в следующей главе, мы концентрируемся на тех особенностях, которые важны для объектно-ориентированного программирования.

C ++ сильный и flexible язык программирования, который был разработан, чтобы положиться на конструкции языка программирования C. Таким образом, с младшим экс-ceptions, C ++ супернабор языка программирования C. C ++ разделяет способность К иметь дело эффективно с аппаратными средствами на уровне битов, байтов, слов, адресов, и т.д. Кроме того, C ++ добавляет несколько улучшений по C (который мотивирует имя «C ++»), с основным улучшением, являющимся ориентированным на объект понятием класса.

Класс - определенный пользователями тип, который заключает в капсулу много важных механизмов такой как гарантируемые инициализацию, неявное преобразование типа, контроль человека памяти - agement, оператор, перегружающий и полиморфизм (которые являются всеми важными темами, которые обсуждены позже в этой книге). У класса также есть способность скрыть не - derlying данные. Это позволяет классу скрывать свои детали внедрения и позволяет пользователям осмыслять класс с точки зрения четко определенного интерфейса. Классы позволяют программистам разбить применение в маленькие, управляемые части или объекты. Получающиеся программы легче понять и легче поддержать.

1.1.1 Простой C ++ программа

Как много языков программирования, создавая и управляя C ++ программа требует

несколько шагов. Во-первых, мы создаем C ++ исходный файл, в который мы входим в линии нашей программы. После того, как мы сохраним этот файл, мы тогда управляем программой, названной компилятором, который

1.1. Основной C ++ программирование элементов 3

создает интерпретацию машинного кода этой программы. Другая программа, названная

компоновщик (который, как правило, призывается автоматически компилятором), включает любые необходимые кодовые необходимые функции библиотеки и производит заключительный машинный исполняемый файл. Чтобы управлять нашей программой, пользователь просит, чтобы система выполнила этот файл.

Давайте полагать, что очень простая программа иллюстрирует некоторые основные элементы языка. Не волнуйтесь, не объяснены ли некоторые элементы в этом примере полностью. Мы обсуждаем их в большей глубине далее в этой главе. Эта программа вводит два целых числа, которые сохранены в переменных x и y. Это тогда вычисляет их сумму и хранит результат в переменной сумме, и наконец это производит эту сумму. (Числа линии не часть программы; они только для нашей справки.)

1 #include <cstdlib> 2 #include <iostream> 3 /* Эта программа вводит два номера x и y и производит их сумму */

4 международное основное ()

5 интервал x, y;

6 станд.:: суд <<«Пожалуйста, введите два номера»:;

7 станд.:: cin>> x>> y; //я nput x и y 8 международная сумма = x + y; //вычисляют их сумму

9 станд.:: суд <<«Их сумма является» <<суммой <<станд.:: endl;

10 возвратите ВЫХОДНОЙ УСПЕХ; //заканчиваются успешно

11 

Несколько вещей об этом C ++ программа должны быть довольно очевидными. Во-первых, комментарии обозначены с двумя разрезами (//). Каждый такой комментарий простирается до конца линии. Более длинные комментарии блока приложены между/* и */. Комментарии блока могут простираться по многократным линиям. Количества, которыми управляет эта программа, сохранены в трех переменных целого числа, x, y, и сумме. Операторы»>>» и» <<» используются для входа и выхода, соответственно.

Элементы программы

Давайте рассмотрим элементы вышеупомянутой программы более подробно. Линии 1 и

2 вводит эти два заголовочных файла, «cstdlib» и «iostream». Заголовочные файлы используются, чтобы предоставить специальные декларации и определения, которые полезны для программы. Первое предоставляет некоторые стандартные системные определения, и второе предоставляет определения, необходимые для входа и выхода.

Начальная точка входа для C ++ программы является главной функцией. Заявление «международное основное ()» на линии 4 объявляет главным, чтобы быть функцией, которая не берет аргументов и возвращает результат целого числа. (В целом главная функция может быть вызвана с аргументами командной строки, но мы не обсуждаем это.) Тело функции дано

в пределах вьющихся скоб ({...}), которые начинаются на линии 4 и конец на линии 11. Программа

заканчивается, когда заявление возвращения о линии 10 выполнено.

4 Глава 1. C ++ учебник для начинающих

В соответствии с соглашением, функция главная прибыль ноль стоимости, чтобы указать на успех и прибыль ненулевое значение, чтобы указать на неудачу. Включать файл cstdlib определяет постоянный ВЫХОДНОЙ УСПЕХ, чтобы быть 0. Таким образом, заявление возвращения о линии 10 прибыли 0, указывая на успешное завершение.

Заявление о линии 6 печатей последовательность, используя оператора продукции (» <<»). Заявление о линии 7 входов ценности переменных x и y использование входного оператора (»>>»). Эти переменные ценности могли поставляться, например, человеком, управляющим нашей программой. Станд. имени:: суд указывает, что производит, должен быть послан в стандартный поток продукции. Есть два других важных потока ввода/вывода в C ++: стандартный вход - то, где введенный, как правило, читается, и стандартная ошибка состоит в том, где ошибочная продукция написана. Это обозначенный станд.:: cin и станд.:: cerr, соответственно.

Префикс «станд.::» указывает, что эти объекты из стандартной библиотеки системы. Мы должны включать этот префикс, обращаясь к объектам из стандартной библиотеки. Тем не менее, возможно сообщить компилятору, что мы хотим использовать объекты из стандартной библиотеки - и тем самым опустить этот префикс - используя заявление «использования» как показано ниже.

#include <iostream>

использование namespace станд.; //делает станд.:: доступный//... единое время co <<«P l e s e e n t e r t w o n u m b e r s»:; //(станд.:: не необходим), ci n>> x>> y;

Мы обсуждаем заявление использования позже в Разделе 1.1.4. Чтобы сохранять наши примеры короткими, мы часто опускаем заявления включаемого и использования, показывая C ++ кодекс. Мы также используем «//..». указать, что некоторый кодекс был опущен.

Возвращаясь к нашему простому примеру C ++ программа, мы отмечаем, что заявление о линии 9 продукции ценность переменной суммы, которая в этом случае хранит вычисленную сумму x и y. По умолчанию заявление продукции не производит конец линии. Специальный станд. объекта:: endl производит специальный характер конца линии. Другой способ произвести конец линии состоит в том, чтобы произвести newline характер, '\n'.

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

Пожалуйста, введите два номера: 7 35 Их сумм равняются 42

1.1.2 Фундаментальные типы

Мы продолжаем наше исследование C ++, обсуждая типы исходных данных языка

и как эти типы представлены как константы и переменные. Фундаментальное

1.1. Основной C ++ программирование элементов 5

типы - основные стандартные блоки, из которых построены более сложные типы.

Они включают следующий.

короткое целое случайной работы bool длинный float дважды

Булево значение, или истинный или ложный характер короткое целое число целого числа длинное число floating-пункта двойной точности числа floating-пункта единственной точности целого числа

Есть также перечисление или enum, напечатайте, чтобы представлять ряд дискретного val - ues. Вместе, перечисления и типы bool, случайную работу и интервал называют составными типами. Наконец, есть специальная пустота типа, которая явно указывает на отсутствие любой информации о типе. Мы теперь обсуждаем каждый из этих типов более подробно.

Знаки

Переменная случайной работы поддерживает единственный характер. Случайная работа в C ++, как правило - 8 битов, но

точное число битов, используемых для переменной случайной работы, зависит от особого imple-процесса мышления. Позволяя различным внедрениям определить значение основных типов, таких как случайная работа, C ++ может скроить ее произведенный кодекс к каждой машинной архитектуре и тем самым достигнуть максимальной производительности. Этот flexibility может быть источником расстройства для программистов, которые хотят написать машинно-независимые программы, как бы то ни было.

Опечатка - постоянная величина, появляющаяся в программе. Опечатки характера

приложенный в единственных кавычках, как в, 'Q', и '+'. Обратная косая черта) is used to

определите много специальных опечаток характера как показано ниже.

'\n'

newline

'\t'

счет

'\b'

клавиша Backspace

'\0'

пустой указатель

'\''

единственная цитата

'\"'

двойная цитата

'\\'

обратная косая черта

Пустой характер, '\0', иногда используется, чтобы указать на конец ряда знаков. Каждый характер связан с кодексом целого числа. Интервал функции (ch) возвращает целочисленное значение, связанное с переменной характера ch.

Целые числа

Международная переменная держит целое число. Целые числа прибывают в три размера: короткое целое, (равнина)

интервал и длинный интервал. Условия, «короткие» и «длинные», являются синонимами для «короткого целого» и «длинного интервала», соответственно. Десятичные числа такой как 0, 25, 98765, и-3 имеют интервал типа. Суффикс «l» или «L» может быть добавлен, чтобы указать на длинное целое число, как в 123456789L. Октальный (базируются 8) константы определены, предварительно фиксировав число с нулевой цифрой, и шестнадцатеричный (базируйтесь 16), константы могут быть определены, предварительно фиксировав число с

6 Глава 1. C ++ учебник для начинающих

«0x». Например, опечатки 256, 0400 и 0x100 все представляют целочисленное значение 256 (в десятичном числе).

Объявляя переменную, у нас есть выбор предоставления определения или начального значения. Если никакое определение не дано, начальное значение непредсказуемо, таким образом, важно, чтобы каждой переменной назначили стоимость прежде чем быть используемым. Имена переменной могут состоять из любой комбинации писем, цифр или подчеркивания () характер, но первый характер не может быть цифрой. Вот некоторые примеры деклараций составных переменных.

короткий n; //стоимость n - неопределенный интервал octalNumber = 0400; //400 (базируются 8), = 256 (базируются 10), случайная работа newline характер = '\n'; длинный BIGnumber = 314159265L;

короткое имя переменной aSTRANGE 1234;

Хотя законно начать имя переменной с подчеркивания, лучше избегать этой практики, начиная с некоторого C ++, компиляторы используют это соглашение для определения их собственных внутренних идентификаторов.

C ++ не определяет точное число битов в каждом типе, но короткими составляют по крайней мере 16 битов, и длинными составляют по крайней мере 32 бита. Фактически, нет никакого требования, что долго быть строго более длинным, чем короткий (но это не может быть короче!). Учитывая тип T, выражение sizeof (T) возвращает размер типа T, выраженного как некоторое число сети магазинов размера случайной работы. Например, на типичных системах, случайная работа 8 битов длиной, и интервал 32 бита длиной, и следовательно sizeof (интервал) 4.

Перечисления

Перечисление - определенный пользователями тип, который может держать любой ряд дискретных ценностей.

После того, как определенный, перечисления ведут себя во многом как тип целого числа. Общее использование перечислений должно обеспечить значащие имена к ряду связанных ценностей. Каждый элемент перечисления связан с целочисленным значением. По умолчанию эти ценности подсчитывают от 0, но также возможно определить явные постоянные величины как показано ниже.

День enumСОЛНЦЕ, ПОНЕДЕЛЬНИК, ВТОРНИК, ЖЕНИЛОСЬ, ЧЕТВЕРГ, ПЯТНИЦА, СИДЕЛ;

Настроение enumСЧАСТЛИВЫЙ = 3, ПЕЧАЛЬНЫЙ = 1, БЕСПОКОЯЩИЙСЯ = 4, СОННЫЙ = 2;

День сегодня = ЧЕТВЕРГ; //сегодня может быть любой ПОНЕДЕЛЬНИК.. СИДЕВШЕЕ Настроение myMood = СОННЫЙ; //myMood может быть СЧАСТЛИВЫМ..., СОННЫЙ

Так как мы не определяли ценности, СОЛНЦЕ будет связано с 0, ПОНЕДЕЛЬНИК с 1, и так далее. Как намек читателю, мы написали имена перечисления и другие константы со всеми заглавными буквами.

1.1. Основной C ++ программирование элементов 7

Плавающая запятая

Переменная типа float держит число floating-пункта единственной точности и vari-

способный из типа дважды держит число floating-пункта двойной точности. Поскольку это делает с целыми числами, C ++ оставляет неопределенным точное число битов в каждом из типов пункта floating. По умолчанию, floating опечатки пункта, такой как 3,14159 и-1234.567 имеют тип дважды. Научный или показательный май примечания указанным использованием или «e» или «E», чтобы отделить мантиссу от образца, как в 3.14E5, что означает

3,14105. Чтобы вынудить опечатку быть float, добавьте суффикс «f» или «F», как в 2.0f или

1.234e-3F.

1.1.3 Указатели, множества и структуры

Мы затем обсуждаем, как объединить фундаментальные типы, чтобы сформировать более сложные.

Указатели

Каждая переменная программы сохранена в памяти компьютера в некотором местоположении, или

адрес. Указатель - переменная, которая держит ценность такого адреса. Учитывая тип T, тип T* обозначает указатель на переменную типа T. Например, интервал* обозначает указатель на целое число.

Два существенных оператора используются, чтобы управлять указателями. Первая прибыль адрес объекта в памяти и вторая прибыль содержание данного адреса. В C ++ первая задача выполнена адресом - оператора, &. Например, если x - переменная целого числа в Вашей программе &x, адрес x в памяти. Доступ к стоимости объекта от ее адреса называют dereferencing. Это сделано, используя * оператор. Например, если мы должны были объявить, что q был указателем на целое число (то есть, интервал*) и затем установил q = &x, мы могли получить доступ к стоимости x с *q. Назначение целочисленного значения к *q эффективно изменяет ценность x.

Рассмотрите, например, кодовый фрагмент ниже. Переменная p, как объявляют, является указателем на случайную работу и инициализирована, чтобы указать на переменную ch. Таким образом *p - другой способ относиться к ch. Заметьте это, когда ценность ch будет изменена, ценность *p изменения также.

случайная работа ch = 'Q';

случайная работа* p = &ch;

//

p ho l ds

адрес ch

единое время co <<* p;

//

продукция

характер 'Q'

ch = 'Z';

//

ch теперь

держит 'Z'

единое время co <<* p;

//

продукция

характер 'Z'

*p = 'X';

//

ch теперь

держится 'X'

единое время co <<c h;

//

продукция

характер 'X'

Мы будем видеть, что указатели очень полезны, строя структуры данных, где Обь - jects связана с друг другом с помощью указателей. Указатели не должны указывать

8

Предостережение

Глава 1. C ++ Учебник для начинающих только к фундаментальным типам, таким как случайная работа и интервал - они могут также указать на сложные типы и даже на функции. Действительно, популярность C ++ происходит частично от его способности обращаться с предприятиями низкого уровня как указатели.

Полезно иметь стоимость указателя, которая не указывает ни на что, то есть, пустой указатель. В соответствии с соглашением, такому указателю назначают ноль стоимости. Попытка к dereference пустой указатель приводит к ошибке во время выполнения. Весь C ++ внедрения определяют специальный ПУСТОЙ УКАЗАТЕЛЬ символа, который равен нолю. Это определение активировано, вставив заявление «#include <cstdlib>» в начале файла программы.

Мы упомянули ранее, что специальная пустота типа используется, чтобы не указать ни на какую информацию о типе вообще. Хотя мы не можем объявить, что переменная пустоты типа, мы можем объявить, что указатель имеет тип void*. Такой указатель может указать на переменную любого типа. Так как компилятор неспособен проверить правильность таких ссылок, использование пустоты*, указателям сильно обескураживают, кроме необычных случаев, где прямой доступ к памяти компьютера необходим.

Остерегайтесь, объявляя два или больше указателя на той же самой линии. * оператор связывает с именем переменной, не с именем типа. Рассмотрите следующую вводящую в заблуждение декларацию.

интервал* x, y, z; //то же самое как: интервал* x; интервал y; интервал z;

Это объявляет одну переменную указателя x, но другие две переменные - простые целые числа. Самый простой способ избежать этого беспорядка состоит в том, чтобы объявить одну переменную за заявление.

Множества

Множество - коллекция элементов того же самого типа. Учитывая любой тип T и a

постоянный N, переменная типа T [N] держит множество элементов N, каждый тип T. На каждый элемент множества ссылаются его индекс, то есть, число от 0 до

N-1.Следующие заявления объявляют два множества; каждый держится три, удваивается и

другие захваты 10 двойных указателей.

двойной f[5]; //множество 5 удваивается: f [0]..., m[10] интервала f[4]; //множество 10 ints: m [0]..., m[9] f[4] = 2.5; m[2] = 4; суд <<f [m[2]]; //продукция f [4], который является 2.5

После того, как объявленный, не возможно увеличить ряд элементов во множестве. Кроме того, C ++ не обеспечивает встроенной проверки времени выполнения множество subscripting за пределы. Это решение совместимо с C ++ общая философия не введение - ducing любая особенность, которая замедлила бы выполнение программы. Индексация множества за пределами его заявленных границ является общей программной ошибкой. Такая ошибка - десять происходит «тихо», и только намного позже является своими замеченными эффектами. В Разделе 1.5.5,

1.1. Основной C ++ программирование элементов 9

мы видим, что векторный тип C ++ Standard Template Library (STL) обеспечивает

многие возможности более полного типа множества, включая проверку индекса во время выполнения и способность динамично изменить размер множества.

Двумерное множество осуществлено как «множество множеств». Например, «интервал [15] [30]» объявляет быть множеством 30 объектов, каждый из которых является множеством 15 целых чисел. Элемент в таком множестве внесен в указатель как [я] [j], где я нахожусь в диапазоне от 0 до 14, и j находится в диапазоне от 0 до 29.

Объявляя множество, мы можем инициализировать его ценности, приложив элементы

во вьющихся скобах ({...}). Делая так, мы не должны определять размер

множество, так как компилятор может понять это.

интервал [] =10, 11, 12, 13; //объявляет и инициализирует [4]

bool b [] =ложный, верный; //объявляет и инициализирует случайную работу b [2] c [] ='c', 't'; //объявляет и инициализирует c[3]

Так же, как возможно объявить множество целых чисел, возможно объявить

множество указателей на целые числа. Например, интервал* r[17] объявляет, что множество r состоит - луг 17 указателей на объекты интервала типа. После того, как инициализированный, мы можем dereference элемент этого множества, используя * оператор, например, *r[16] - ценность целого числа, на которое указывает последний элемент этого множества.

Указатели и множества

Есть интересная связь между множествами и указателями, какой C ++ inher-ited с языка программирования C - название множества эквивалентно указателю на начальный элемент множества и наоборот. В примере ниже, c - множество знаков, и p и q - указатели на первый элемент c. Они все ведут себя по существу то же самое, как бы то ни было.

случайная работа c [] ='c', 't';

случайная работа* p = c; //p указывает на c [0]

случайная работа* q = &c [0]; //q также указывает на c [0] суд <<c[2] <<p[2] <<q[2]; //продукция «ttt»

Эта эквивалентность между именами множества и указателями может быть запутывающей, но она помогает

Предостережение

объяснить многие C ++ очевидные тайны. Например, учитывая два множества c и d, сравнение (c == d) не проверяет, равно ли содержание двух множеств. Скорее это сравнивает адреса их начальных элементов, который является, вероятно, не, что имел в виду программист. Если есть потребность выполнить операции на всех множествах (таких как копирование одного множества другому), это - хорошая идея использовать векторный класс, который является частью C ++ Стандартная Библиотека Шаблона. Мы обсуждаем эти понятия в Разделе 1.5.5.

10 Глава 1. C ++ учебник для начинающих

Последовательности

Буквальная последовательность, такой как «Привет Мир», представлена как множество фиксированной длины

знаки, который заканчивается пустым характером. Строки символов, представленные таким образом, называют последовательностями C-стиля, так как они были унаследованы от C. К сожалению, одно только это представление не обеспечивает много операций по последовательности, таких как страна concate-и сравнение. Это также обладает всеми особенностями C ++ множества, как отмечалось ранее.

Поэтому C ++ обеспечивает тип последовательности как часть его Standard Template Library (STL). Когда мы должны различить, мы называем эти последовательности STL. Чтобы использовать последовательности STL, необходимо включать заголовочный файл <последовательность>. Так как последовательности STL - часть стандарта namespace (см. Раздел 1.1.4), их полное имя - станд.:: последовательность. Добавляя заявление «использование станд.:: последовательность», сообщаем мы компилятору, что хотим получить доступ к этому определению непосредственно, таким образом, мы можем опустить «станд.::» префикс. Последовательности STL могут быть связаны, используя + оператор, они могут быть друг по сравнению с другом использующим лексикографический (или словарь) заказ, и они могут быть входом и выходом, используя>> и <<операторы, соответственно. Например:

#include <последовательность>

использование станд.:: последовательность;//... натяните s =, «чтобы быть»;

натяните t = «не» + s;

//

t = «чтобы не быть»

натяните u = s + «или» + t;

//

u = «чтобы быть или не быть»

если (s> t)

//

верный: «чтобы быть»>, «чтобы не быть»

единое время co <<u;

//

продукция, «чтобы быть или не быть»

Есть другие операции по последовательности STL, также. Например, мы можем приложить тот

натяните к другому использованию + = оператор. Кроме того, последовательности могут быть внесены в указатель как множества, и число знаков в последовательности s дан s.size (). Так как некоторые функции библиотеки требуют старых последовательностей C-стиля, есть конверсионная функция s.c str (), который возвращает указатель на последовательность C-стиля. Вот некоторые примеры:

натяните s = «Джон»;

//

s = «Джон»

интервал i = s.size ();

//

i=4

случайная работа c = s[3];

//

c = 'n'

s + = «Смит»;

//

теперь s = «Джон Смит»

C ++ STL предоставляет многим другим операторам последовательности включая операторов для экс-

tracting, поиск и замена подстрок. Мы обсуждаем некоторые из них в Секунду - tion 1.5.5.

Структуры C-стиля

Структура полезна для хранения скопления элементов. В отличие от множества,

элементы структуры могут иметь различные типы. Каждый участник или область, a

1.1. Основной C ++ программирование элементов 11

структура упомянута именем. Например, рассмотрите следующий struc-

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

enum MealTypeНИКАКАЯ ПРИСТАВКА, РЕГУЛЯРНАЯ, ОБЕЗЖИРЕННАЯ, ВЕГЕТАРИАНСКАЯ;

Пассажир struct

последовательность имя; // первенство s инженер er имя

MealType mealPref; // предпочтение еды

b o ol isFreqFlyer; // в частой flyer программе? последовательность freqFlyerNo; // частота пассажира flyer число

;

Это определяет новый тип под названием Пассажир. Давайте объявим и давайте инициализируем переменную, названную «проходом» этого типа.

Пассажирский проход =«Джон Смит», ВЕГЕТАРИАНЕЦ, верный, «293145»;

К отдельным членам структуры получают доступ, используя членский выбор

оператор, у которого есть форма struct name.member. Например, мы могли изменить некоторые вышеупомянутые области следующим образом.

pass.name = «Покахонтас»; //chang e называют pass.mealPref = РЕГУЛЯРНЫМ; //изменяют предпочтение еды

Структуры того же самого типа могут быть назначены на друг друга. Например, если p1 и p2 имеют Пассажира типа, то p2 = p1 копирует элементы p1 к p2.

Что мы обсудили, до сих пор мог бы быть назван структурой C-стиля. C ++ про - vides намного более сильное и конструкция flexible назвал класс, в котором могут быть объединены и данные и функции. Мы обсуждаем классы в Разделе 1.5.

Указатели, динамическая память и «новый» оператор

Мы часто считаем полезным в структурах данных создать объекты динамично как потребность

возникает. C ++ система во время выполнения резервирует большой блок памяти, названной свободным магазином, поэтому. (Эту память также иногда называют памятью кучи, но это не должно быть перепутано со структурой данных кучи, которая обсуждена в Главе 8.) Оператор, новый динамично, ассигнует правильную сумму хранения для объекта данного типа из свободного магазина и возвращает указатель на этот объект. Таким образом, ценность этого указателя - адрес, где этот объект проживает в памяти. Действительно, C ++ допускает переменные указателя к любому типу данных, даже к другим указателям или к отдельным клеткам во множестве.

12

Глава 1. C ++ учебник для начинающих

Например, предположите, что в нашей системе авиакомпании мы сталкиваемся с новым пассажиром. Мы хотели бы динамично создать новый случай, используя нового оператора. Позвольте p быть указателем на Пассажирскую структуру. Это подразумевает, что *p относится к фактической структуре; следовательно, мы могли получить доступ к одному из его участников, сказать mealPref область, используя выражение (*p) .mealPref. Поскольку сложные объекты как структуры часто ассигнуются динамично, C ++ обеспечивает более короткий способ получить доступ к участникам, использующим «->» оператор.

имя указателя-> участник эквивалентно (*pointer имя), .member, Например, мы могли ассигновать новый пассажирский объект и инициализировать его участников следующим образом.

Пассажир *p;

// . . .

p = новый Пассажир;

p-> называют = «Покахонтас»;

p-> mealPref = РЕГУЛЯРНЫЙ; p-> isFreqFlyer = ложный; p-> freqFlyerNo = «НИ ОДИН»;

//p указывает новому Пассажиру//, устанавливает участников структуры

Было бы естественно задаться вопросом, можем ли мы инициализировать участников, использующих вьющееся

скоба ({...}) Примечание, используемое выше. Ответ не, но мы будем видеть другого больше

удобный способ инициализировать участников, когда мы обсуждаем классы и конструкторов

в Разделе 1.5.2.

Этот новый пассажирский объект продолжает существовать в свободном магазине, пока это явно не удалено - процесс, который сделан, используя удалить оператора, который разрушает объект и возвращает его пространство в свободный магазин.

удалите p; //разрушают объект p, указывает на

Удалить оператор должен только быть применен к объектам, которые были ассигнованы

через новый. Так как объект по адресу p был ассигнован, используя нового оператора, C ++, система во время выполнения знает, сколько памяти, чтобы освободить для этого удаляют заявление. В отличие от некоторых языков программирования, таких как Ява, C ++ не делает про - смотри автоматическая сборка мусора. Это означает, что C ++ программисты несут ответственность явного удаления всех динамично ассигнованных объектов.

Множества могут также быть ассигнованы с новым. Когда это сделано, системное лицо, ведающее распределением возвращает указатель на первый элемент множества. Таким образом динамично ассигнованное множество с элементами типа T было бы объявлено, имея тип *T. Множества, ассигнованные этим способом, не могут быть освобождены, используя стандарт, удаляют оператора. Вместо этого оператор удаляют [], используется. Вот пример, который ассигнует буфер характера 500 элементов, и затем позже освобождает его.

случайная работа* буферизует = новая случайная работа [500]; //ассигнуют буфер 500 случайных работ

буфер [3] = 'a'; //к элементам все еще получают доступ, используя [], удаляют [] буфер; //удаляют буфер

1.1. Основной C ++ программирование элементов 13

Утечки памяти

Отказ удалить динамично ассигнованные объекты может вызвать проблемы. Если мы должны были изменить (адрес) ценность p без первого удаления структуры, на которую это указывает, не было бы никакого способа для нас получить доступ к этому объекту. Это продолжило бы существовать для целой жизни программы, израсходовав пространство, которое могло иначе быть использовано для других ассигнованных объектов. Наличие таких недоступных объектов в динамической памяти называют утечкой памяти. Мы должны сильно избежать утечек памяти, особенно в программах, которые делают большое распределение памяти и освобождение. Программа с утечками памяти может исчерпать применимую память, даже когда есть достаточный существующий объем памяти. Важное правило для дисциплинированного C ++ программист является следующим:

Помнить

Если объект ассигнован с новым, он должен в конечном счете быть освобожден с

удалить.

Ссылки

Указатели обеспечивают один способ относиться косвенно к объекту. Иначе через ссылки. Ссылка - просто альтернативное название объекта. Учитывая тип T, примечание T& указывает на ссылку на объект типа T. В отличие от указателей, которые могут быть ПУСТЫМИ, ссылка в C ++ должна относиться к фактической переменной. Когда ссылка объявлена, ее стоимость должна быть инициализирована. Впоследствии, любой доступ к ссылке рассматривают точно, как будто это - доступ к основному объекту.

натяните автора = «Сэмюэль Клеменс»;

string& псевдоним = автор; //псевдоним - псевдоним для автора p enN ame = «M r k T w я n»; //теперь автор = суд «Марка Твена» <<автор; //продукция «Марк Твен»

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

1.1.4 Названные константы, объем и Namespaces

Мы можем легко назвать переменные без беспокойства об обозначении conflicts в маленьком prob-

lems. Намного более трудно для нас избежать conflicts в больших системах программного обеспечения, которые могут состоять из сотен файлов, написанных многими различными программистами. C ++ имеет много механизмов, которые помогают в обеспечении имен и ограничении их объема.

14 Глава 1. C ++ учебник для начинающих

Constants и Typedef

Хорошим программистам обычно нравится связывать имена с постоянными количествами.

Добавляя константу ключевого слова к декларации, мы указываем, что ценность связанного объекта не может быть изменена. Константы могут использоваться фактически где угодно, что опечатки могут использоваться, например, в декларации множества. Как намек читателю, мы будем использовать все заглавные буквы, называя константы.

константа двойное ПИ

=

3.14159265;

интервал константы УБЕЖАЛ []

=

9 0, 8 0, 7 0, 6 0;

интервал константы N ДНИ

=

7;

интервал константы N ЧАСЫ

=

24*N ДНИ;//использование постоянного выражения

международный прилавок [N ЧАСЫ];

//множество 168 ints

Обратите внимание на то, что перечисления (см. Раздел 1.1.2) обеспечивают другой удобный способ de - прекрасные константы со знаком целого числа, особенно в пределах структур и классов.

В дополнение к соединению имен с константами часто полезно связать имя с типом. Эта ассоциация может быть сделана с typedef декларацией. Вместо того, чтобы объявлять переменную, typedef определяет новое имя типа.

случайная работа typedef* BuferPtr; //печатают BuferPtr, указатель, чтобы обуглить typedef двойная Координата; //Координата типа - двойное

BuferPtr p; //p - указатель на Координату x, y случайной работы; //x и y имеют тип дважды

При помощи typedef мы можем обеспечить короче или более значащие синонимы для различных типов. Имя типа Координата предоставляет больше намека читателю значения переменных x и y, чем действительно удваивается. Кроме того, если позже мы решаем изменить наше координационное представление интервалу, мы должны только изменить typedef заявление. Мы будем следовать соглашению указания на определенные пользователями типы capi-talizing первый характер их имен.

Местные и глобальные объемы

Когда группа C ++ заявления приложена во вьющихся скобах ({...}), они определяют

блок. Переменные и типы, которые объявлены в пределах блока, только доступны

из блока. Они, как говорят, местные к блоку. Блоки могут быть вложены в пределах других блоков. В C ++, переменная может быть объявлена за пределами любого блока. Такая переменная глобальна, в том смысле, что это доступно отовсюду в программе. Части программы, из которой имя доступно, называют его объемом.

Две переменные того же самого имени могут быть определены в пределах вложенных блоков. Когда это происходит, переменная внутреннего блока становится активной до отъезда блока.

1.1. Основной C ++ программирование элементов 15

Таким образом местная переменная «скрывает» любые глобальные переменные того же самого имени как показано в

следующий пример.

интервал константы Кэт = 1;

международное основное ()

интервал константы Кэт = 2;

суд <<Кошка; возвратите ВЫХОДНОЙ УСПЕХ;

международная собака = Кэт;

Namespaces

//глобальная Кэт

//эта Кэт местная к основному//продукция 2 (местная Кэт)

//собака = 1 (от глобальной Кэт)

Глобальные переменные представляют много проблем в больших системах программного обеспечения, потому что к ним можно получить доступ и возможно изменить где угодно в программе. Они также могут привести к программированию ошибок, так как важная глобальная переменная может быть скрыта местной переменной того же самого имени. В результате лучше избегать глобальных переменных. Мы можем не быть в состоянии избежать globals полностью, как бы то ни было. Например, когда мы выполняем продукцию, мы фактически используем глобальный стандартный объект потока продукции системы, суд. Если мы должны были определить переменную с тем же самым именем, то поток суда системы будет недоступен.

namespace - механизм, который позволяет группе связанных имен быть определенной в одном месте. Это помогает организовать глобальные объекты в естественные группы и минимизирует проблемы globals. Например, следующее объявляет namespace myglob-Альсом, содержащим две переменные, кошку и собаку.

namespace myglobals

международная кошка;

натяните собаку = «гав-гав»;

Namespaces может обычно содержать определения более сложных объектов, включая типы, классы и функции. Мы можем получить доступ к объекту x в namespace группе, нас - луг примечание group::x, который называют его полностью составным именем. Например, myglobals:: кошка обращается к копии переменной кошки в myglobals namespace.

Мы уже видели пример namespace. Многие стандартная система Обь - jects, такая как стандартные потоки входа и выхода cin и суд, определены в системе namespace названный станд. Их полностью составные имена - станд.:: cin и станд.:: суд, соответственно.

16 Глава 1. C ++ учебник для начинающих

Использование заявления

Если мы неоднократно используем переменные от того же самого namespace, возможно

избегите входить в namespace спецификаторы, говоря системе, что мы хотим «использовать» особый спецификатор. Мы сообщаем это желание, используя заявление использования, которое делает некоторых или все имена от namespace доступного, явно не обеспечивая спецификатор. У этого заявления есть две формы, которые позволяют нам перечислять отдельные имена или делать каждое имя в namespace доступном как показано ниже.

использование станд.:: последовательность; //делает просто станд.:: натяните доступный станд. использования:: суд; //делает просто станд.:: доступный суд

использование namespace myglobals; //делает все myglobals доступными

1.2

Выражения

Выражение объединяет переменные и опечатки с операторами, чтобы создать новую стоимость. В следующем обсуждении мы группируем операторов согласно типам объектов, к ним можно относиться. Повсюду, мы используем вар, чтобы обозначить переменную или что-либо, на которое может быть назначена стоимость. (В чиновнике К ++ жаргон, это называют lvalue.) Мы используем exp, чтобы обозначить выражение и тип, чтобы обозначить тип.

Членский выбор и индексация

Некоторые операторы получают доступ к члену структуры, класса или множества. Мы позволяем названию класса

обозначьте название структуры или класса; указатель обозначает указатель на структуру или класс, и множество обозначает множество или указатель на первый элемент множества.

название класса. членский членский выбор класса/структуры

указатель-> членский членский выбор класса/структуры

множество [exp] множество subscripting

Арифметические операторы

Следующее - операторы двоичной арифметики:

exp + exp дополнение

exp- вычитание exp

exp * exp умножение

exp / exp подразделение exp % exp модуль (остаток)

Там также одноместны минус (-x) и одноместны плюс (+x) операции. Подразделение быть - подросток два операнда целого числа приводит к результату целого числа усечением, даже если