|
Программирование >> Инициализация объектов класса, структура
Стандартная библиотека С++ имеет заголовочный файл limits, содержащий различную информацию о встроенных типах данных, в том числе и диапазоны значений для каждого типа. Заголовочные файлы climits и cfloat также содержат эту информацию. (Об использовании этих заголовочных файлов для того, чтобы избежать переполнения и потери значимости, см. главы 4 и 6 [pLAUGER]92]). Арифметика вещественных чисел создает еще одну проблему, связанную с округлением. Вещественное число представляется фиксированным количеством разрядов (разным для разных типов - float, double и long double), и точность значения зависит от используемого типа данных. Но даже самый точный тип long double не может устранить ошибку округления. Вещественная величина в любом случае представляется с некоторой ограниченной точностью. (См. [SHAMPINE97] о проблемах округления вещественных чисел.) Упражнение 4.1 Примечание [O.A.1]: Как должны б1ть оформлены ссылки на книги, указанные в библиографии? Пришлите ваши пожелания. double dvall = 10.0, dva12 = 3.0; int ivall = 10, iva12 = 3; dvall / dva12; В чем разница между приведенными выражениями с операцией деления? ivall / iva12; Упражнение 4.2 Напишите выражение, определяющее, четным или нечетным является данное целое число. Упражнение 4.3 Найдите заголовочные файлы limits, climits и cfloat и посмотрите, что они содержат. 4.3. Операции сравнения и логические операции Таблица 4.2. Операции сравнения и логические операции
Операции сравнения и логические операции в результате дают значение типа bool, то есть true или false. Если же такое выражение встречается в контексте, требующем целого значения, true преобразуется в 1, а false - в 0. Вот фрагмент кода, подсчитывающего количество элементов вектора, меньших некоторого заданного vector<int>::iterator iter = ivec.beg-in() ; while ( iter != ivec.end() ) { эквивалентно: e1em cnt = e1em cnt + (*iter < some va1ue) значение true/false важения *iter < some va1ue превращается в 1 или 0 e1em cnt += *iter < some va1ue; ++iter; значения: Mi просто прибавляем результат операции меньше к счетчику. (Пара += обозначает составной оператор присваивания, который складывает операнд, стоящий слева, и операнд, стоящий справа. То же самое можно записать более компактно: elem count = elem count + n. Mы рассмотрим такие операторы в разделе 4.4.) Логическое И (&&) возвращает истину только тогда, когда истинны оба операнда. Логическое ИЛИ () дает истину, если истинен хотя бы один из операндов. Гарантируется, что операнда: вычисляются слева направо и вычисление заканчивается, как только результирующее значение становится известно. Что это значит? Пусть даны expr1 && expr2 два выражения: expr1 expr2 Если в первом из них expr1 равно false, значение всего выражения тоже будет равным false вне зависимости от значения expr2, которое даже не будет вычисляться. Во втором выражении expr2 не оценивается, если expr1 равно true, поскольку значение всего выражения равно true вне зависимости от expr2. Подобный способ вычисления дает возможность удобной проверки нескольких while ( ptr != О && ptr->va1ue < upperBound && ptr->va1ue >= 0 && notFound( ia[ ptr->va1ue ] )) выражений в одном операторе AND: { ... } Указатель с нулевым значением не указывает ни на какой объект, поэтому применение к нулевому указателю операции доступа к члену вызвало бы ошибку (ptr->value). Однако, если ptr равен 0, проверка на первом шаге прекращает дальнейшее вычисление подвыражений. Аналогично на втором и третьем шагах проверяется попадание величины bool found = false; пока элемент не найден и ptr указает на объект (не 0) while ( ! found ss ptr ) { found = 1ookup( *ptr ); ++ptr; наоборот. Например: Подвыражение ! found дает true, если переменная found равна false. Это более компактная запись для found == false Аналогично if ( found ) эквивалентно более длинной записи if ( found == true ) Использование операций сравнения достаточно очевидно. Нужно только иметь в виду, что, в отличие от И и ИЛИ, порядок вычисления операндов таких выражений не Внимание! Порядок вгчислений не определен! if ( ia[ index++ ] < ia[ index ] ) ia[ index ] определен. Вот пример, где возможна подобная ошибка: поменять местами элементы Программист предполагал, что левый операнд оценивается первым и сравниваться будут элементы ia[0] и ia[1]. Однако компилятор не гарантирует вычислений слева направо, и в таком случае элемент ia[0] может быть сравнен сам с собой. Гораздо лучше if ( ia[ index ] < ia[ index+1 ] ) поменять местами элементы написать более понятный и машинно-независимый код: ++index; ptr->value в нужный диапазон, и операция взятия индекса не применяется к массиву ia, если этот индекс неправилен. Операция логического НЕ дает true, если ее единственный оператор равен false, и
|
© 2006 - 2025 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки. |