Песни о Паскале | страница 122





Рис.75 – Изменение числовых переменных при переполнении и антипереполнении

Такая вот чудная арифметика! Причина переполнений и антипереполнений кроется в устройстве регистров процессора, — в свое время мы узнаем о них больше при изучении двоичной системы счисления. Или вспомните одометр — прибор для подсчёта пробега автомобиля: по достижении предельного количества километров (99999) одометр сбрасывается в ноль.

Сейчас важно понять, что присвоение переменной некоторого выражения не гарантирует правильного результата, – он будет верным лишь при отсутствии переполнений и антипереполнений. Когда в вычислении участвуют переменные разных типов, оно выполняется в самом емком формате, то есть в Longint, а затем результат «обрубается» в соответствии с типом принимающей переменной, например:


>{ $R- }

>var B: Byte; S: ShortInt;       W: Word; N: Integer;

>      ...

>      N:= B + S + W;


Здесь даже при положительных значениях всех суммируемых операндов, результат в переменной N может оказаться отрицательным! Если вам не по нраву такое поведение программы, включайте директиву проверки диапазонов $R+.

Инкремент и декремент

Угадайте, что чаще всего делают с целыми переменными? — прибавляют и вычитают единицу. Потому в процессорах стараются ускорить эти операции. Паскаль не обошел вниманием эту особенность программ, и предлагает вам две процедуры, объявленные так:


>procedure Inc (var N : longint); { прибавление единицы к переменной N }

>procedure Dec (var N : longint); { вычитание единицы из переменной N }


Хотя параметр N в процедурах объявлен как LONGINT, в действительности здесь может стоять переменная любого порядкового типа: INTEGER, WORD, BYTE, CHAR и даже BOOLEAN.


>var B: byte; N: integer; C: char;

>  ...

>  Inc(B); { B:= B+1 }

>  Dec(N); { N:= N–1 }

> C:= ‘A‘; Inc(C); { ‘B‘}


Процедуры инкремента и декремента – так их называют – выполняются быстрее операторов присваивания N:=N+1 и N:=N-1.

Работающим в IDE Borland Pascal, следует учесть, что здесь процедуры инкремента и декремента не подвластны директиве $R+ (в отличие от сложения и вычитания). То есть, переполнения и антипереполнения не вызывают аварий.

Диапазоны

Контроль переполнений директивой $R+ повышает надежность программ. Но порой нужны более сильные ограничения. Предположим, некая переменная M по смыслу является порядковым номером месяца в году. Стало быть, её значения должны быть ограничены диапазоном от 1 до 12. Программист может указать это компилятору, объявив переменную как диапазон, и явно задав допустимые пределы её изменения: