Определение и инициализация объектов данных
Теперь, чтобы завладеть вниманием пользователя, выполним короткий тест. Мы отобразим два числа из числовой последовательности и предложим пользователю угадать следующие значения в последовательности. Например,
The values 2,3 from two consecutive elements of a numerical sequence. What is the next value?
Эти значения - третий и четвертый элементы из последовательности Фибоначчи: 1, 1, 2, 3, 5, 8, 13 и т. д. Последовательность Фибоначчи начинается с двух элементов - единиц. Каждый следующий элемент это сумма двух предшествующих.
Если пользователь введет 5, мы поздравим его и спросим, хочет ли он попробовать другую числовую последовательность. Любое другое введенное значение - неверно, и мы спросим пользователя, хочет ли он погадать еще.
Чтобы поддержать интерес к программе, мы сохраним текущий счет, основанный на отношении правильных ответов к числу попыток.
Программа нуждается, по меньшей мере, в пяти объектах: объекте строкового класса для сохранения имени пользователя, трех целых объектах класса для запоминания по очереди попыток, числа попыток, числа успешных попыток, и объект класса чисел с плавающей точкой для запоминания счета.
Для определения объектов данных мы должны ввести имена и тип данных. Имена могут быть любыми комбинациями букв, цифр, подчеркиваний. Буквы регистрозависимые. Каждое из имен user_name, User_name, uSeR_nAmE и user_Name относится к разным объектам.
Имя не должно начинаться с цифры. Например, l_name неправильно, name_l - правильно. Также имя не должно совпадать с ключевыми словами языка. Например, delete - ключевое слово языка, так что мы не должны использовать его в нашей программе. (Это объясняет, почему оператор удаления символа из строкового класса - это erase (), а не deleted).
Каждый объект должен быть своего типа данных. Имя объекта позволяет нам обратиться к нему непосредственно. Тип данных определяет область значений, сохраняемых объектом, и количество памяти, необходимой для запоминания этого значения.
Мы видели определение user_name в предыдущем разделе. Перенесем то же определение в новую программу:
#include <string> string user_name;
Класс - программно-определенный тип данных. С++ также поддерживает множество встроенных типов данных: булевы, целые, с плавающей точкой и символьные. Ключевые слова, ассоциированные с каждым из них, позволяют нам определить тип данных. Например, для запоминания значения, введенного пользователем, мы определим объект целого типа:
Int usr_val;
Int - ключевое слово языка определяющее, что объект usr_val - целого типа. Оба объекта: число попыток, сделанных пользователем и число правильных ответов, - объекты целого типа. Разница только в том, что мы бы хотели дать им начальное значение «О». Мы можем вывести каждое на отдельную строку:
Int num_.trіes = 0; int num_right = 0;
Или определить их в одной строке через запятую:
Int num_tries = 0, num_right = 0;
В общем, лучше придерживаться правила инициализировать объект данных, даже если значение только обозначает, что объект не имеет полезного значения вовсе. Я не инициализировал usr_val, потому что значение будет получено непосредственно из пользовательского ввода прежде, чем программа как-то использует объект.
Альтернативный вариант инициализации - использовать так называемый конструкционный синтаксис
Int num_.tries (0);
Почему есть два инициализационных синтаксиса? Хуже того, почему я сейчас об этом говорю? Что ж, посмотрим, отвечает ли мое объяснение на оба вопроса.
Использование оператора присваивания для инициализации пришло из языка С. Оно хорошо работает с объектами данных встроенных типов и классами объектов, которые могут быть инициализированы единственным значением, например строковым классом:
String sequence_name = "Fibonacci";
Однако данный способ не так хорош для класса объектов, которые требуют нескольких значений для инициализации, как, например, класс стандартной библиотеки комплексных чисел, где каждое требует двух значений: первое - для действительной части, второе - для мнимой. Альтернативный конструкционный синтаксис был введен для поддержки многозначной инициализации:
#include <complex> complex<double> pureі(0, 7);
Странная нотация скобок, следующая за complex, означает, что класс комплексных чисел - класс шаблонов. Класс шаблонов позволяет нам определять класс без спецификации типа данных одного или всех членов класса.
Класс комплексных чисел, например, состоит из двух членов объекта данных. Один представляет реальную часть числа, второй - мнимую. Эти члены должны быть числами типа данных с плавающей точкой, но какого? С++ поддерживает три типа чисел с плавающей точкой: единичной точности, представляемых ключевым словом float; двойной точности, представленной ключевым словом double; и расширенной
Точности, представленной двумя ключевыми словами long double.
Механизм класса шаблонов позволяет программисту откладывать определение типа данных, используя класс шаблонов. Это дает ему возможность вставить «заглушку», которую позднее он заполнит реальным типом данных. В предыдущем примере использовался выбор данных типа класса комплексных чисел double.
Что ж, возможно, появляется больше вопросов, чем получается ответов. Это происходит от того, что шаблоны, под держиваемые С++, двух инициализационных синтаксисов для встроенных типов данных. Когда встроенные типы данных и программно определенный класс типов имеют разный иници- ализационный синтаксис, невозможно написать шаблон, который поддерживает и встроенный класс, и класс типа данных. Унификация синтаксиса упрощает разработку шаблонов. К сожалению, раскрытие синтаксиса приводит к появлению еще большей путаницы!
Счет пользователя должен быть значением с плавающей точкой, поскольку возникает нецелое отношение. Мы определим его типом double:
Double usr_score = 0.0;
Нам также нужно сохранить место для ответов пользователя yes/по: Make another try? Try another sequence?
Мы можем сохранить ответы пользователя в символьном объекте данных:
Char usr_more;
Cout « "Try another sequence? Y/N? "; cin » usr_more;
Ключевое слово char относится к символьному типу. Символ окаймляется апострофами, обозначая ' а', ' 7 ', '; ' и т. д. Некоторые специальные встроенные символьные обозначения приведены ниже (их иногда называют эскейп последовательности):
n' newline (новая строка) "t" tab (табуляция) "