Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
C++ для начинающих (Стенли Липпман) 3-е хххх.pdf
Скачиваний:
84
Добавлен:
30.05.2015
Размер:
5.92 Mб
Скачать

С++ для начинающих

107

 

(a) int ival = 1.01;

(b) int &rval1 = 1.01;

 

 

(c) int &rval2 = ival;

(d) int &rval3 = &ival;

 

(e) int *pi = &ival;

(f) int &rval4 = pi;

 

(g) int &rval5 = pi*;

(h) int &*prval1 = pi;

Есть ли ошибки в данных определениях? Поясните. Как бы вы их исправили?

(i) const int &ival2 = 1; (j) const int &*prval2 = &ival;

Упражнение 3.20

Если ли среди нижеследующих операций присваивания ошибочные (используются

(a)rval1 = 3.14159;

(b)prval1 = prval2;

(c)prval2 = rval1;

определения из предыдущего упражнения)?

(d) *prval2 = ival2;

Упражнение 3.21

(a)int ival = 0; const int *pi = 0; const int &ri = 0;

(b)pi = &ival; ri = &ival;

Найдите ошибки в приведенных инструкциях: pi = &rval;

3.7. Тип bool

// инициализация строки

string search_word = get_word();

// инициализация переменной found bool found = false;

string next_word;

while ( cin >> next_word )

if ( next_word == search_word ) found = true;

//...

//сокращенная запись: if ( found == true ) if ( found )

cout << "ok, мы нашли слово\n";

Объект типа bool может принимать одно из двух значений: true и false. Например: else cout << "нет, наше слово не встретилось.\n";

Хотя bool относится к одному из целых типов, он не может быть объявлен как signed, unsigned, short или long, поэтому приведенное определение ошибочно:

С++ для начинающих

108

// ошибка

short bool found = false;

Объекты типа bool неявно преобразуются в тип int. Значение true превращается в 1, а

bool found = false;

int occurrence_count = 0;

while ( /* mumble */ )

{

found = look_for( /* something */ );

// значение found преобразуется в 0 или 1 occurrence_count += found;

false в 0. Например:

}

Таким же образом значения целых типов и указателей могут быть преобразованы в

// возвращает количество вхождений extern int find( const string& ); bool found = false;

if ( found = find( "rosebud" ))

//правильно: found == true

//возвращает указатель на элемент extern int* find( int value );

if ( found = find( 1024 ))

значения типа bool. При этом 0 интерпретируется как false, а все остальное как true:

//правильно: found == true

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

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

const int input = 1; const int output = 2;

Конечно, можно определить три константы для обозначения этих режимов: const int append = 3;

и пользоваться этими константами:

С++ для начинающих

109

bool open_file( string file_name, int open_mode);

// ...

open_file( "Phoenix_and_the_Crane", append );

Подобное решение допустимо, но не вполне приемлемо, поскольку мы не можем гарантировать, что аргумент, передаваемый в функцию open_file() равен только 1, 2 или 3.

Использование перечислимого типа решает данную проблему. Когда мы пишем:

enum open_modes{ input = 1, output, append };

мы определяем новый тип open_modes. Допустимые значения для объекта этого типа ограничены набором 1, 2 и 3, причем каждое из указанных значений имеет мнемоническое имя. Мы можем использовать имя этого нового типа для определения как объекта данного типа, так и типа формальных параметров функции:

void open_file( string file_name, open_modes om );

input, output и append являются элементами перечисления. Набор элементов перечисления задает допустимое множество значений для объекта данного типа. Переменная типа open_modes (в нашем примере) инициализируется одним из этих значений, ей также может быть присвоено любое из них. Например:

open_file( "Phoenix and the Crane", append );

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

// ошибка: 1 не является элементом перечисления open_modes

перечисления, мы все равно получим ошибку: open_file( "Jonah", 1 );

Есть способ определить переменную типа open_modes, присвоить ей значение одного из

open_modes om = input;

// ...

элементов перечисления и передать параметром в функцию:

om = append;

open_file( "TailTell", om );

Однако получить имена таких элементов невозможно. Если мы напишем оператор вывода:

cout << input << " " << om << endl;

то все равно получим:

С++ для начинающих

110

1 3

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

cout << open_modes_table[ input ] << " "

такой массив, мы сможем написать:

 

<< open_modes_table[ om ]

<< endl

 

 

 

Будет выведено:

 

input append

// не поддерживается

for ( open_modes iter = input; iter != append; ++inter )

Кроме того, нельзя перебрать все значения перечисления:

// ...

Для определения перечисления служит ключевое слово enum, а имена элементов задаются в фигурных скобках, через запятую. По умолчанию первый из них равен 0, следующий 1 и так далее. С помощью оператора присваивания это правило можно изменить. При этом каждый следующий элемент без явно указанного значения будет на 1 больше, чем элемент, идущий перед ним в списке. В нашем примере мы явно указали значение 1 для

// shape == 0, sphere == 1, cylinder == 2, polygon == 3

input, при этом output и append будут равны 2 и 3. Вот еще один пример: enum Forms{ share, spere, cylinder, polygon };

Целые значения, соответствующие разным элементам одного перечисления, не обязаны

// point2d == 2, point2w == 3, point3d == 3, point3w == 4

отличаться. Например:

enum Points { point2d=2, point2w, point3d=3, point3w=4 };

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

соответствующие допустимым элементам перечисления целые значения не могут быть ему присвоены: