Программирование >>  Инициализация объектов класса, структура 

1 ... 43 44 45 [ 46 ] 47 48 49 ... 395


int ival = 1024;

и проверку результата разыменования. Если ptr определен как

int *ptr = sival;

то результатом разыменования будет 1024 и оба сравнения дадут истину. Результатом всего выражения также будет истина (оператор && обозначает логическое И).

Если посмотреть на этот пример внимательно, можно заметить, что порядок выполнения операций очень важен. Скажем, если бы операция разыменования ptr производилась до его сравнения с 0, в случае нулевого значения ptr это скорее всего вызвало бы крах программы. В случае операции И порядок действий строго определен: сначала оценивается левый операнд, и если его значение равно false, правый операнд не вычисляется вовсе. Порядок выполнения операций определяется их приоритетами, не всегда очевидными, что вызывает у начинающих программистов на С и С++ множество ошибок. Приоритете! будут приведены в разделе 4.13, а пока м1 расскажем обо всех операциях, определенных в С++, начиная с наиболее привычных.

4.2. Арифметические операции

Таблица 4.1. Арифметические операции

7 Проверку на неравенство 0 можно опустить. Полностью эквивалентна приведенной и более употребима следующая запись: ptr && *ptr.

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

*ptr

* представляет собой унарную операцию разыменования. Значением этого выражения является значение объекта, адрес которого содержится в ptr. Если же написать:

var1 * var2

то звездочка будет обозначать бинарную операцию умножения.

Результатом вычисления выражения всегда, если не оговорено противное, является г-значение. Тип результата арифметического выражения определяется типами операндов. Если операнды имеют разные типы, производится преобразование типов в соответствии с нредонределенным набором правил. (Mi детально рассмотрим эти правила в разделе

4.14.)

Выражение может являться составным, то есть объединять в себе несколько подвыражений. Вот, например, выражение, проверяющее на неравенство нулю указатель и объект, на который он указывает (если он на что-то указывает)7:

ptr != 0 ss *ptr != 0 Выражение состоит из трех подвыражений: проверку указателя ptr, разыменования ptr



Символ операции

Значение

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

Умножение

expr * expr

Деление

expr / expr

Остаток от деления

expr % expr

Сложение

expr + expr

Вычитание

expr - expr

Деление целых чисел дает в результате целое число. Дробная часть результата, если она

int ivall

21 / 6;

есть, отбрасывается:

int iva12 = 21 / 7; И ival1 , и ival2 в итоге получат значение 3.

Операция остаток (%), называемая также делением по модулю, возвращает остаток от деления первого операнда на второй, но применяется только к операндам целого типа (char, short, int, long). Результат положителен, если оба операнда положительны. Если же один или оба операнда отрицательны, результат зависит от реализации, то есть машинно-зависим. Вот примеры правильного и неправильного использования деления по

3.14 % 3; ошибка: операнд типа double правильно: 3 правильно: 0

21 % 6; 21 % 7; 21 % -5;

правильно: правильно: машинно-зависимо: -1 или 1

int iva1 = 1024; double dval = 3.14159;

iva1 % 12; правильно:

модулю:

iva1 % dval; ошибка: операнд типа double

Иногда результат вычисления арифметического выражения может быть неправильным либо не определенным. В этих случаях говорят об арифметических исключениях (хотя они не вызывают возбуждения исключения в программе). Арифметические исключения могут иметь чисто математическую природу (скажем, деление на 0) или происходить от представления чисел в компьютере - как переполнение (когда значение превышает величину, которая может быть выражена объектом данного типа). Например, тип char содержит 8 бит и способен хранить значения от 0 до 255 либо от -128 до 127 в зависимости от того, знаковый он или беззнаковый. В следующем примере попытка присвоить объекту типа char значение 256 вызывает переполнение:



#include <iostream>

int main() {

char byte value int ival = 8;

переполнение памяти, отведенной под byte value byte value = ival * byte value;

cout << byte value: static cast<int>(byte value) << endl;

Для представления числа 256 необходима: 9 бит. Переменная byte value получает некоторое неопределенное (машинно-зависимое) значение. Допустим, на нашей рабочей станции SGI мы получили 0. Первая попытка напечатать это значение с помощью:

cout << byte va1ue: << byte va1ue << endl; привела к результату:

i byte value:

После некоторого замешательства м1 поняли, что значение 0 - это нулевой символ ASCII, который не имеет представления при печати. Чтобы напечатать не представление символа, а его значение, нам пришлось использовать весьма странно выглядящее выражение:

static cast<int>(byte value)

которое называется явным приведением тина. Оно преобразует тин объекта или выражения в другой тип, явно заданный программистом. В нашем случае мы изменили byte value на int. Теперь программа выдает более осмысленный результат:

[ byte value: 0

На самом деле нужно было изменить не значение, соответствующее byte value, а поведение операции вывода, которая действует по-разному для разных типов. Объекты тина char представляются ASCII-символами (а не кодами), в то время как для объектов типа int мы увидим содержащиеся в них значения. (Преобразования типов рассмотрены в разделе 4.14.)

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



1 ... 43 44 45 [ 46 ] 47 48 49 ... 395

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика