1 Составные типы данных. 2 Язык C++ предлагает для этого составные типы, сформированные на основе базовых целочисленных типов и типов с плавающей точкой.

Презентация:



Advertisements
Похожие презентации
Практическое занятие 6. Функции. Большинство языков программирования используют понятия функции и процедуры. C++ формально не поддерживает понятие процедуры,
Advertisements

Функции Функция – именованная последовательность описаний и операторов, выполняющая некоторое действие. Может иметь параметры и возвращать значение. Функция.
Основы информатики Классы Заикин Олег Сергеевич zaikin.all24.org
Работа с файлами Сазонов Д.О. ПМиЭММ Часть 2. Тема занятия: Работа с файлами через потоки Для реализации файлового ввода/вывода, необходимо включить в.
Структуры и объединения Structures and unions НГТУ ИРИТ кафедра ИСУ Ольга Пронина.
«Типы данных». Целочисленные типы данных Тип ДиапазонТребуемая память (байт) byte shortint integer word longint
Основы информатики Массивы. Указатели. Заикин Олег Сергеевич
Основы информатики Лекция. Массивы. Указатели. Заикин Олег Сергеевич
УКАЗАТЕЛИ. Переменная - это именованная область памяти с заданным типом. [=значение]; int a; //Переменная типа integer с именем a int b=2;// Переменная.
Тема: массивы в PHP Изучить возможности языка PHP при решении задач, требующих использования массивов. Рассмотреть примеры использования массивов при создании.
МАССИВЫ 4 Определение 4 Описание 4 Обращение к элементам массива 4 Связь массивов с указателями 4 Примеры программ.
План-конспект урока (информатика и икт, 9 класс) по теме: Переменные:тип, имя, значение
Лекция 4 Программирование на Паскале. Элементы языка Турбо Паскаль 7.0. Типы данных. Управляющие конструкции.
Объектно-ориентированный язык программирования. Переменная - эта поименованная ячейка памяти, хранящая какое-либо одно значение (одно число, один фрагмент.
Лекция 2 С => C++ => C# Большие и маленькие буквы различаются (main, Main, MAIN, mAin – разные имена) После каждого оператора ставится точка с запятой.
Понятие строки. Операции со строковыми величинами. Стандартные процедуры и функции обработки строковых величин. Простые алгоритмы работы со строками на.
Файловый тип данных Файл – это область памяти на внешнем носителе, в которой хранится некоторая информация. В языке Паскаль файл представляет собой последовательность.
Что такое связи между таблицами В реляционной базе данных связи позволяют избежать избыточности данных. Например, в ходе создания базы данных, содержащей.
Переменные и операторы УРОК 2. Переменные ПЕРЕМЕННАЯ – ?... контейнер для хранения данных. Переменная имеет имя – это….? последовательность букв, цифр.
Теперь, когда вы постигли азы программирования, будем учиться писать программы, которые позволяют вести диалог между компьютером и человеком (пользователем).
Транксрипт:

1 Составные типы данных

2 Язык C++ предлагает для этого составные типы, сформированные на основе базовых целочисленных типов и типов с плавающей точкой. Наиболее перспективный составной тип это класс. Однако C++ также поддерживает несколько более простых составных типов. Массив, например, может содержать несколько значений одного и того же типа данных. Массив специфического вида может включать строку, которая представляет собой ряд символов. Структуры могут содержать несколько значений различных типов. Существуют еще указатели, являющиеся переменными, которые указывают компьютеру адреса хранения данных. В этой главе будут рассмотрены все перечисленные составные формы данных, а также впервые представлены операторы new и delete.

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

4 Краткий обзор массивов Объявление массива в C++ реализуется путем изменения объявления простой переменной за счет добавления квадратных скобок, в которых содержится число элементов. Например, объявление short months[12]; // создает массив из 12 элементов типа short создает массив с именем months, который содержит 12 элементов. Каждый из них может хранить значение типа short. Общая форма записи для объявления массива выглядит так: typeName arrayName[arraySize];

5 Краткий обзор массивов Многие свойства массива базируются на возможности обращаться к элементам массива по отдельности. Для этого нужно использовать индекс, который позволяет перечислять элементы. Нумерация массивов в языке C++ начинается с 0. Для указания элемента массива в языке C++ используется запись индекса в квадратных скобках. Например, months [0] первый элемент массива months, a months [11] последний. Индекс последнего элемента на единицу меньше, чем размер массива. Таким образом, объявление массива дает возможность создать несколько переменных одним объявлением, после чего можно использовать индекс, чтобы идентифицировать отдельные элементы и обращаться к ним.

6 Краткий обзор массивов

7 Компилятор не контролирует допустимость указываемого индекса. Например, если присвоить значение несуществующему элементу массива months [101], то компилятор не выдаст сообщения об ошибке. Однако в результате такого присвоения могут возникнуть ошибки во время выполнения программы, что приведет к повреждению данных или кода, либо вызовет аварийное завершение программы. Поэтому программисту необходимо позаботиться о том, чтобы в программе использовались только допустимые значения индекса.

8 Краткий обзор массивов

9

10 Краткий обзор массивов Как уже упоминалось, оператор sizeof возвращает размер типа или объекта данных в байтах. Заметим, что если оператор sizeof используется с именем массива, то выводится общее количество байтов массива. Если же sizeof используется с элементом массива, возвращается размер элемента в байтах

11 Правила инициализации массивов

12 Правила инициализации массивов Если массив инициализируется частично, то транслятор устанавливает для оставшихся элементов нулевые значения. Таким образом, можно легко присвоить всем элемен­там массива нуль нужно лишь явно присвоить нуль первому элементу и предоставить компилятору инициализировать оставшиеся элементы: float totals [500] = {0}; Если при инициализации массива квадратные скобки оставить пустыми, компилятор C++ самостоятельно вычислит количество его элементов. Предположим, что выполняется следующее объявление: short things[] = {1, 5, 3, 8}; Компилятор создает массив things из четырех элементов.

13 Строки Строка это ряд символов, хранящихся в последовательно расположенных байтах памяти. В языке C++ есть два способа обработки строк. Первый, позаимствованный из С (он часто называется строкой С- стиля), будет рассмотрен в этой главе. Позже вы познакомитесь с альтернативным методом обработки строк, основанным на библиотеке классов string. Принцип хранения ряда символов в последовательных байтах памяти подразумевает, что можно хранить строку в массиве символов (char), с тем, чтобы каждый символ содержался в своем собственном элементе массива.

14 Строки

15 Строки

16 Строки

17 Конкатенация строк

18 Использование строк в массиве Существует два наиболее способа записи строки в массив: первый инициализация массива строковой константой, второй считывание в массив результатов ввода с клавиатуры. Это проиллюстрировано в листинге 4.2: одному массиву присваивается строка в кавычках, а для помещения введенной строки в другой массив применен объект cin. Кроме того, в программе используется функция стандартной библиотеки strlen(), чтобы узнать длину строки. Стандартный заголовочный файл cstring обеспечивает объявления для этой и многих других функций, связанных со строками.

19 Использование строк в массиве

20 Использование строк в массиве

21 Использование строк в массиве

22 Использование строк в массиве Оператор sizeof возвращает полный размер массива, 15 байтов, однако функция strlen() возвращает размер сохраненной в массиве строки, а не размер массива непосредственно. Кроме того, strlen() подсчитывает только видимые символы, нулевой символ исключается.

23 Использование строк в массиве

24 Использование строк в массиве Программа strings.cpp имеет недостаток, который не проявился, т.к. был "замаскирован" за счет отбора примеров ввода данных. В листинге 4.3 "маскировка" отсутствует и демонстрируется, что при вводе строк могут возникать проблемы.

25 Использование строк в массиве

26 Использование строк в массиве

27 Использование строк в массиве Как видим, пользователю даже не дали возможности ответить на приглашение ввести название десерта! Программа, показав это приглашение, тут же стала выполняться дальше, чтобы вывести заключительную строку. Проблема заключается в том способе, при помощи которого cin определяет конец ввода строки. Поскольку ввести нулевой символ с клавиатуры нельзя, cin нуждается в каких-то других средствах для определения конца строки. Принцип работы cin основан на допущении, что для ограничения строки используются пробельные символы символы пробела, табуляции и символы новой строки. Это означает, что cin считывает только одно слово, когда оно становится входным для символьного массива, и помещает строку в массив, автоматически добавляя конечный нулевой символ.

28 Использование строк в массиве На практике у нас получилось следующее: cin читает Alistair как полную первую строку и помещает ее в массив name, а слово Dreeb остается в очереди ввода. Когда cin ищет очередь ввода для ответа на вопрос о любимом десерте, то находит там слово Dreeb. Тогда cin, недолго думая, "проглатывает" Dreeb и помещает слово в массив dessert (рис. 4.4). Есть еще одна проблема, которая не проявилась в приведенном диалоге. Она заключается в том, что входная строка могла бы оказаться длиннее, чем массив назначения. Использование cin в этом примере не дает возможности предотвратить помещение 30- символьной строки в 20-символьный массив.

29 Использование строк в массиве

30 Ввод, ориентированный на строки: функции getline() и get() В данном случае применяется другой подход: строчно-ориентированный метод вместо текстового метода. К счастью, класс istream, которому принадлежит объект cin, содержит некоторые строчно-ориентированные функции-элементы. Функция getline(), например, читает целую строку, используя переданный с помощью клавиши ENTER символ новой строки, чтобы пометить конец ввода. Для обращения к этому методу используется следующий вызов функции: cin.getline(). Функция требует передачи двух параметров. Первый имя массива, предназначенного для сохранения введенной строки, а второй ограничивает количество символов, которые нужно считать.

31 Ввод, ориентированный на строки: функции getline() и get() Если этот предел составляет, скажем, 20, функция читает не больше чем 19 символов, оставляя участок памяти, чтобы автоматически добавить нулевой символ в конец. Функция-элемент getline() прекращает чтение входных данных, когда достигает числового предела или когда читает символ новой строки, в зависимости от того, какое из двух событий происходит первым. Предположим, что нужно использовать функцию getline(), чтобы считать название в 20-элементный массив name. Необходимо выполнить следующий запрос: cin.getline(name,20); Этот запрос считывает строку целиком в массив name при условии, что строка состоит из 19 или меньшего количества символов

32 Ввод, ориентированный на строки: функции getline() и get()

33 Ввод, ориентированный на строки: функции getline() и get() Результат выполнения программы: Enter your name: Dirk Hammernose Enter your favorite dessert: Radish Torte I have some delicious Radish Torte for you, Dirk Hammernose.

34 Ввод, ориентированный на строки: функции getline() и get() Теперь программа читает полные имена и отображает для пользователя заказанные десерты! Функция getline() воспринимает строку "в один присест". Она читает вводимые данные до символа новой строки, который обозначает конец строки, однако не сохраняет его, а заменяет при сохранении строки нулевым символом.

35 Ввод, ориентированный на строки: функции getline() и get() Теперь рассмотрим другой подход. Класс istream содержит еще одну функцию-элемент, которая называется get() и имеет несколько разновидностей. Одна из ее разновидностей очень похожа по своим действиям на getline(). Ей требуются те же самые параметры, интерпретируются они точно так же, и она считывает входные данные до конца строки. Однако get (), вместо того чтобы считать и удалить символ новой строки, оставляет его во входной очереди.

36 Ввод, ориентированный на строки: функции getline() и get() Если, предположим, мы используем два запроса get () подряд: cin.get(name, ArSize); cin.get(dessert, Arsize); // проблема то поскольку в результате первого вызова символ новой строки остается во входной очереди, он будет первым символом, который доступен для второго запроса. Таким образом, get(), не найдя символов, подлежащих считыванию, заключает, что достигла конца строки. И без дополнительной помощи get() не сможет преодолеть этот символ новой строки.

37 Ввод, ориентированный на строки: функции getline() и get() Реально ли получить такую помощь? Вполне реально, и на помощь здесь приходит еще одна разновидность функции get(). В результате вызова функции cin.get() (без параметров) происходит считывание только одного следующего символа, даже если это символ новой строки. Этим можно воспользоваться, чтобы избавиться от символа новой строки и приготовиться к приему следующей строки ввода. Поэтому приведенная ниже последовательность операторов даст нам желаемый результат: cin.get(name, ArSize); // читает первую строку cin.get() ; // читает символ новой строки cin.get(dessert, Arsize); // читает вторую строку

38 Ввод, ориентированный на строки: функции getline() и get() Есть еще один способ использования get() конкатенировать, или объединить, эти две функции-элементы класса следующим образом: cin.get(name,ArSize).get(); //объединение функций-элементов Это возможно благодаря тому, что выражение cin. get (name, ArSize) возвращает объект cin, который затем используется как объект, вызывающий функцию get().

39 Ввод, ориентированный на строки: функции getline() и get() Аналогично, выражение cin.getline(name1, ArSize).getline(name2, ArSize); считывает две последовательные входные строки в массивы name1 и name2, что эквивалентно выполнению двух отдельных вызовов функции cin.getline (). В листинге 4.5 используется конкатенация функций.

40 Ввод, ориентированный на строки: функции getline() и get()

41 Ввод, ориентированный на строки: функции getline() и get() Результат выполнения программы: Enter your name: Mai Parfait Enter your favorite dessert: ChocolateMousse I have some delicious Chocolate Mousse for you, Mai Parfait.

42 Ввод, ориентированный на строки: функции getline() и get() Отметим как в C++ реализованы множественные версии функций с различающимися списками параметров. Если используется, скажем, выражение cin.get(name,ArSize), компилятор отмечает, что необходима форма, которая помещает строку в массив, и устанавливает соответствующую функцию-элемент. Если вместо этого используется выражение cin.get(), компилятор понимает, что вам нужна форма, которая читает один символ. Эта функциональная возможность, которая называется перегрузкой функции, будет подробно рассмотрена далее.

43 Ввод, ориентированный на строки: функции getline() и get() Зачем вообще использовать функцию get () вместо getline () ? Во-первых, в более ранних реализациях C++ может вообще не оказаться функции getline(). Во-вторых, функция get() позволяет предотвратить ошибки. Предположим, что функция get() использована для того, чтобы считывать строку в массив. Как узнать, что эта функция прочла целую строку, а не остановилась по причине того, что массив заполнен? Это можно определить по очередному символу в очереди ввода. Если это символ новой строки, значит, была считана целая строка. Если это не символ новой строки, значит, в строке все еще имеется что-то для ввода. Итак, функцию getline () использовать несколько легче, но get() упрощает исправление ошибок. Для чтения строки ввода можно пользоваться любой из этих функций, но следует учитывать различия в их поведении.

44 Пустые строки и другие проблемы Что происходит после того, как функция getline () или get() считает пустую строку? Первоначально было принято, чтобы следующий оператор начинал ввод с того места, где остановилась последняя функция getline () или get (). Однако сейчас после того, как функция get() (но не getline()) считывает пустую строку, она устанавливает флаг называемый failbit (бит ошибки). Смысл этого действия состоит в том, что дальнейший ввод блокирован, но его можно восстановить с помощью следующей команды: cin.clear();

45 Пустые строки и другие проблемы Другая потенциальная проблема заключается в том, что длина введенной строки может превышать размер выделенной для нее памяти. Если введенная строка содержит больше указанного количества символов, обе функции как get (), так и getline() оставляют оставшиеся символы во входной очереди. Однако getline(), помимо этого, устанавливает бит ошибки и прекращает дальнейший ввод.

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

47 Смешанный ввод строк и чисел

48 Смешанный ввод строк и чисел Результат выполнения этой программы будет выглядеть примерно так: What year was your house built? 1966 What is its street address? Year built: 1966 Address: Done!

49 Смешанный ввод строк и чисел При работе с данной программой пользователь никогда не получит возможности ввести адрес. Проблема состоит в том, что объект cin, считав значение года, оставляет символ новой строки, сгенерированный с помощью клавиши ENTER, во входной очереди. Затем функция cin.getline() воспринимает символ новой строки так, как будто это пустая строка, и присваивает нулевую строку элементу массива address.

50 Смешанный ввод строк и чисел Чтобы исправить ошибку, следует считать и отбросить символ новой строки перед чтением адреса. Это можно сделать несколькими способами, включая использование функции get() без параметров или с параметром типа char, как описано в предшествующем примере. Можно вызвать функцию отдельно: cin » year; cin.get(); // или cin.get(ch); Можно также конкатенировать функции, воспользовавшись тем, что выражение cin » year возвращает объект cin: (cin » year).get();// или (cin » year).get(ch);

51 Смешанный ввод строк и чисел Если внести одно из этих изменений в листинг 4.6, программа начнет работать корректно: What year was your house built? 1966 What is its street address? Unsigned Short Street Year built: 1966 Address: Unsigned Short Street

52 Краткий обзор структур Предположим, что нужно сохранить информацию об игроке в баскетбол. Сюда входят следующие данные: имя, заработок, рост, вес, средний рейтинг, процент попаданий и т.д. Необходимо иметь некоторую форму данных, которая может содержать всю эту информацию в одном блоке. Массив для этого не годится, поскольку все его элементы должны быть одного типа. Иначе говоря, один массив может содержать двадцать элементов типа int, а другой десять элементов типа float, но один и тот же массив не может содержать элементы типа int и float.

53 Краткий обзор структур Решение состоит в применении структуры. Структура более универсальная форма данных, чем массив, поскольку может содержать элементы, относящиеся к различным типам данных. Использование структуры позволяет унифицировать представление данных путем сохранения всей связанной с баскетболистом информации в единственной переменной структуры, для ведения данных по целой команде можно использовать массив структур. Тип структуры также служит мостиком к классу, который является основой ООП языка C++.

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

55 Краткий обзор структур Предположим, компания Bloataire хочет создать некий тип для описания видов надувных изделий. В частности, этот тип должен содержать название изделия, его объем в кубических футах и цену. Ниже приведено описание структуры, удовлетворяющей перечисленным условиям: struct inflatable // описание структуры { char name[20]; // элемент типа array float volume; // элемент типа float double price; // элемент типа double };

56 Краткий обзор структур Ключевое слово struct указывает на то, что код определяет компоновку структуры. Идентификатор inflatable имя, или дескриптор, для этой формы. Таким образом, inflatable представляет собой имя нового типа данных. Между фигурными скобками находится список типов данных, которые содержатся в структуре. Каждый элемент списка это оператор объявления. Здесь можно использовать любой из типов данных C++, включая массивы и другие структуры. В этом примере применяется массив типа char, удобный для сохранения строки, а также float и double. Каждый отдельный элемент в списке называется элементом структуры, так что структура inflatable включает три элемента.

57 Краткий обзор структур Когда шаблон готов, можно создавать переменные данного типа: inflatable hat; // hat структурная переменная типа inflatable inflatable woopie_cushion; // структурная переменная типа inflatable inflatable mainframe; // структурная переменная типа inflatable в C++ при объявлении переменных структуры можно опускать ключевое слово struct. struct inflatable goose; // в языке С ключевое слово struct обязательно inflatable vincent; // в C++ ключевое слово struct необязательно

58 Краткий обзор структур

59 Краткий обзор структур Поскольку переменная hat имеет тип inflatable, для обращения к отдельным элементам можно использовать оператор принадлежности (.). Например, выражение hat.volume указывает на элемент volume структуры, a hat.price на элемент price. Аналогично vincent.price элемент price переменной vincent. Имена элементов предоставляют возможность обращения к элементам структуры во многом подобно тому, как индексы позволяют обращаться к элементам массива. Поскольку элемент price объявлен как тип double, элементы hat.price и vincent.price эквивалентны переменным типа double. Таким образом, hat это структура, но hat.price элемент типа double. Кстати, этот метод используется для обращения к функциям-элементам класса.

60 Краткий обзор структур

61 Краткий обзор структур

62 Краткий обзор структур Результат выполнения программы: Expand your guest list with Glorious Gloria and Audacious Arthur! You can have both for $62.98!

63 Краткий обзор структур Где следует размещать объявление структуры. Можно поместить объявление внутрь функции main(), сразу после открывающей фигурной скобки. Второй вариант, который реализован здесь, поместить объявление вне функции main (), а именно перед ней. Когда объявление размещается вне любой функции, оно называется внешним объявлением. Для программ, состоящих из двух или более функций, выбор варианта может иметь большое значение. Внешнее объявление может использоваться всеми функциями, следующими за ним, тогда как внутреннее объявление может быть использовано только функцией, в которой оно содержится.

64 Краткий обзор структур

65 Краткий обзор структур Рассмотрим следующую процедуру инициализации: inflatable guest = { "Glorious Gloria", // имя 1.88, // объем // цена };}; Как и в случае с массивами, используется список значений, разделенных запятыми и заключенных в пару фигурных скобок. Программа размещает по одному значению в строке, но их можно размещать все в одной строке. Главное не забывать разделять элементы запятыми: inflatable duck = {"Daphne", 0.12, 9.98};

66 Краткий обзор структур Каждый элемент структуры можно инициализировать с присвоением приемлемого значения. Например, элемент name символьный массив, поэтому его можно инициализировать с присвоением строкового значения. Каждый элемент структуры обрабатывается как переменная соответствующего типа. Таким образом, элемент pal.price - переменная типа double, a pal.name массив элементов типа char. Когда программа использует объект cout, чтобы вывести значение pal.name, этот элемент отображается в виде строки. Поскольку pal.name символьный массив, для обращения к его отдельным символам можно использовать индексы. Например, pal.name[0] это символ A. Но выражение pal[0] не имеет смысла, потому что pal это структура, а не массив.

67 Другие свойства структур В языке C++ определяемые пользователем типы настолько близки по свойствам к встроенным типам, насколько это возможно. Например, можно передавать структуры функциям в качестве аргументов, а также использовать структуру, как возвращаемое значение функции. Кроме того, допускается использование оператора присвоения (=), чтобы присвоить значение одной структуры другой структуре того же типа. Такое действие приводит к тому, что каждому элементу одной структуры будет присвоено значение соответствующего элемента другой структуры, даже если этот элемент массив. Данный вид операций называется поэлементным присваиванием. Тему передачи и возвращения структур мы пока отложим на будущее, пока не познакомимся с функциями, однако присвоение значений структурам бегло рассмотрим уже сейчас.

68 Другие свойства структур

69 Другие свойства структур

70 Другие свойства структур Ниже приводится результат выполнения программы: bouquet: sunflowers for $12.49 choice: sunflowers for $12.49 Как видим, здесь выполнено поэлементное присваивание: элементам структуры choice присвоены те же самые значения, что хранились в структуре bouquet.

71 Другие свойства структур Можно комбинировать определение формы структуры с созданием переменных структуры. Для этого после закрывающей фигурной скобки следует указать имена одной или нескольких переменных:

72 Другие свойства структур

73 Другие свойства структур Можно также создавать структуру без имени типа. При этом имя структуры (дескриптор) опускается, но определяется форма структуры и ее переменные: struct// без названия { int x;// два элемента int у; } position; // переменная структуры В приведенной выше программе создается одна переменная структуры с именем position. К ее элементам можно обращаться с помощью оператора принадлежности, например position.х, но для типа нет никакого общего названия и впоследствии вы не сможете создавать другие переменные того же типа.

74 Массивы структур Структура inflatable содержит массив (с именем name). Можно также создавать массивы, элементы которых будут структурами. Методика точно такая же, как и при создании массивов базовых типов данных. В следующем примере создается массив из 100 структур inflatable: inflatable gifts[100];// массив из 100 структур inflatable В результате будет создан массив gifts типа inflatable. Следовательно, каждый элемент массива, такой как gifts [0] или gifts [99], это объект типа inflatable, и его можно использовать с оператором принадлежности: cin » gifts[0].volume; // используется элемент volume первой структуры cout « gifts[99].price « endl; // отобразить элемент price последней структуры

75 Массивы структур Следует иметь в виду, что сам gifts это массив, а не структура, так что такие конструкции, как gifts.price, не являются корректными.

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

77 Массивы структур В итоге получается заключенный в фигурные скобки список значений с разделением запятыми. Каждое значение также представляет собой заключенный в фигурные скобки список значений, разделенных запятыми: inflatable guests[2] = // инициализация массива структур { {"Bambi", 0.5, 21.99}, // первая структура массива {"Godzilla", 2000, } // следующая структура массива } ;

78 Битовые поля В C++, как и в С, обеспечивается возможность определять элементы структуры, которые занимают указанное количество битов. Тип поля должен быть целочисленным или типом перечисления (перечисления описываются далее в этой главе), а двоеточие, за которым следует число, указывает фактическое количество битов, или разрядов, которые нужно использовать. Для создания интервала можно применять неименованные поля. Каждый элемент называется битовым полем. Например: struct torgle_register { int SN : 4; // четыре разряда для значения SN int : 4; // четыре разряда не используются bool goodln : 1; // корректный ввод (один разряд) bool goodTorgle : 1;// успешное присвоение };

79 Битовые поля Для обращения к битовым полям используется стандартная система обозначений структуры: torgle_register tr; if (tr.goodln) Битовые поля обычно применяются в программировании низкого уровня. В качестве альтернативы битовым полям во многих случаях можно использовать переменные целочисленного типа и поразрядные операторы, список которых приведен в приложении Е.

80 Объединения Объединение это формат данных, который может содержать различные типы данных, но только один тип одновременно. Иначе говоря, в то время как структура может содержать, скажем, элементы типа int, long, и double, объединение может содержать значения типа int, или long, или double. Синтаксис описания объединения выглядит так же, как и для структуры, но имеет другой смысл. Рассмотрим следующее объявление: union one4all { int int_val; long long_val; double double_val; );

81 Объединения Переменную one4ail можно использовать для хранения элемента типа int, long или double, но не одновременно: one4all pail; pail.int_yal = 15; // содержит значение типа int cout « pail.int_jval; pail.double_val = 1.38; // содержит double, значение int утрачено cout « pail. double_jval; Таким образом, pail может служить как переменная типа int в одном случае и как переменная типа double в другом. Имя элемента идентифицирует роль переменной. Поскольку объединение содержит только одно значение одновременно, оно должно иметь объем, достаточный для того, чтобы сохранить самый большой элемент. Следовательно, размер объединения соответствует размеру его самого большого элемента.

82 Объединения Одна из целей применения объединения экономия памяти. Для элемента данных можно использовать два или большее количество форматов, но не одновременно. Предположим, требуется вести учет различных изделий, часть из которых представлена целочисленными идентификаторами, а часть строковыми. Тогда можно реализовать следующее объявление:

83 Объединения

84 Объединения Анонимное объединение не имеет никакого имени; в сущности, его элементы становятся переменными, которые используют один адрес. Естественно, в одно и то же время текущим может быть только один элемент:

85 Объединения

86 Объединения Поскольку объединение анонимно, id_num и id_char трактуются как два элемента prize, которые совместно используют один и тот же адрес. Потребность в промежуточном идентификаторе id_val устранена. Программист должен следить за тем, какой из вариантов активен.

87 Перечисления Средство языка C++ enum обеспечивает способы создания символических констант, альтернативные объявлению при помощи ключевого слова const. Данное средство также позволяет определять новые типы данных, но довольно ограниченным способом. Синтаксис для использования перечисления похож на синтаксис описания структуры. Рассмотрим следующий оператор: enum spectrum {red, orange, yellow, green, blue, violet, indigo, ultraviolet};

88 Перечисления Этот оператор выполняет две функции: Делает слово spectrum именем нового типа данных; spectrum называется перечислением, подобно тому как переменная struct называется структурой. Определяет red, orange, yellow и т.д. как символические константы для целых чисел от 0 до 7. Эти константы называются перечислителями. По умолчанию перечислители определяются как целые значения, начиная с 0 для первого перечислителя, 1 для второго и т.д.

89 Перечисления Имя перечисления можно использовать для того, чтобы объявить переменную этого типа: spectrum band ; Переменная перечисления имеет некоторые специальные свойства, которые мы рассмотрим далее. Единственными допустимыми значениями, которые можно присваивать переменной типа перечисления без преобразования типа, являются значения перечислителей, использованные в определении типа.