Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Языки программирования. Практический сравнитель...doc
Скачиваний:
54
Добавлен:
09.09.2019
Размер:
2.68 Mб
Скачать

2.4. Оператор присваивания

Удивительно, что в обычных языках программирования есть только один опера­тор, который фактически что-то делает, — оператор присваивания. Все другие операторы, такие как условные операторы и вызовы процедур, существуют только для того, чтобы управлять последовательностью выполнения операто­ров присваивания. К сожалению, трудно формально определить смысл опера­тора присваивания (в отличие от описания того, что происходит при его вы­полнении); фактически, вы никогда не встречали ничего подобного при изуче­нии математики в средней школе и колледже. То, что вы изучали, — были урав­нения:

ах2 + bх + с = О

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

Скромный оператор присваивания на самом деле является очень сложным и решает три разные задачи:

1. Вычисление значения выражения в правой части оператора.

2. Вычисление выражения в левой части оператора; выражение должно определять адрес ячейки памяти.

3. Копирование значения, вычисленного на шаге 1, в ячейки памяти, начи­ная с адреса, полученного на шаге 2.

Таким образом, оператор присваивания

a(i + 1) = b + c;

несмотря на внешнее сходство с уравнением, определяет сложное вычисление.

2.5. Контроль соответствия типов

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

Контроль соответствия типов — это проверка того, что тип выражения совместим с типом адресуемой переменной при присваивании. Сюда входит и присваивание фактического параметра формальному при вы­зове процедуры.

Возможны следующие подходы к контролю соответствия типов:

• Не делать ничего; именно программист отвечает за то, чтобы присваива­ние имело смысл.

• Неявно преобразовать значение выражения к типу, который требуется в левой части.

Строгий контроль соответствия типов: отказ от выполнения присваива­ния, если типы различаются.

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

Строгий контроль соответствия типов может исключить скрытые ошибки, которые обычно вызываются опечатками или недоразумениями. Это особенно важно в больших программных проектах, разрабатываемых группами програм­мистов; из-за трудностей общения, смены персонала, и т.п. очень сложно объ­единять такое программное обеспечение без постоянной проверки, которой является строгий контроль соответствия типов. Фактически, строгий конт­роль соответствия типов пытается превратить ошибки, возникающие во вре­мя выполнения программы, в ошибки, выявляемые при компиляции. Ошиб­ки, проявляющиеся только во время выполнения, часто чрезвычайно трудно найти, они опасны для пользователей и дорого обходятся разработчику про­граммного обеспечения в смысле отсрочки сдачи программы и испорченной репутации. Цена ошибки компиляции незначительна: вам, вероятно, даже не требуется сообщать своему начальнику, что во время компиляции произошла ошибка.

2.6. Управляющие операторы

Операторы присваивания обычно выполняются в той последовательности, в какой они записаны. Управляющие операторы используются для измене­ния порядка выполнения. Программы на языке ассемблера допускают про­извольные переходы по любым адресам. Язык программирования по анало­гии может включать оператор goto, который осуществляет переход по мет­ке на произвольный оператор. Программы, использующие произвольные переходы, трудно читать, а следовательно, изменять и поддерживать.

Структурное программирование — это название, данное стилю программи­рования, который допускает использование только тех управляющих опера­торов, которые обеспечивают хорошо структурированные программы, легкие для чтения и понимания. Есть два класса хорошо структурированных управ­ляющих операторов.

• Операторы выбора, которые выбирают одну из двух или нескольких альтернативных последовательностей выполнения: условные операто­ры (if) и переключатели (case или switch).

• Операторы цикла, в которых повторяется выполнение последовательно­сти операторов: операторы for и while.

Хорошее понимание циклов особенно важно по двум причинам: 1) боль­шая часть времени при выполнении будет (очевидно) потрачена на циклы, и 2) многие ошибки связаны с неправильным кодированием начала или конца цикла.