Т. Пратт, М. Зелковиц - Языки программирования - разработка и реализация (4-е издание_ 2002) (1160801), страница 98
Текст из файла (страница 98)
А++ (А--) Возвращает значение переменной А, затем увеличивает (илиуменьшает) ее значение на 1 (сначала возвращает гзначение А, затем А - А ~ 1). Хотя все эти операции похожи друг на друга, но каждая имеет немного отличную от других семантику и может приводить к разным эффектам в различных ситуациях. Поскольку основной операцией присваивания является присваивание г-значения одного выражения 1-значению другого выражения, можно достичь большей гибкости, если иметь операции, воздействующие на г-значения и 1-значения переменных.
Например, в языке С унарная операция разадресации * является операцией, которая заставляет г.-значение переменной вести себя так, как будто А=В А+= В (--) В языке С присваивацие является просто операцией, так что можно написать: с = Ь = 1; согласно порядку приоритетов, представленному в табл. 8 2,данная запись означает (с = 1Ь = 1) ) и ей соответствует следующий вычислительный процесс 1. Переменной Ь присваивается значение 1.
2. Выражение (Ь = !) возвращаетзначение 1. 3. Переменной с присваивается значение 1. Чаще, однако, присваивание рассматривается как отдельный оператор. Поскольку операция присваивания языка Рааса! не возвращает никакого явного результата, мы используем ее только на уровне операторов в явном операторе присваивания: Х:= В + В*С: Ч -Я~Х; В большинстве языков имеется единственная операция присваивания.
Однако в языке С их несколько; 350 Глава 8. Управление последовательностьюдействий оно является 1-значением. А унарная операция взятия адреса а, наоборот, преобразует 1-значение в г-значение. Рассмотрим пример: тпт т. *р: р и *р Здесь происходит следующее: 1) объявляется целая переменная т; 2) р объявляется как указатель на целую переменную; 3) р устанавливается как указатель на т, то есть йзначение переменной т преобразуется в гзначенис (Ьт ) и это г-значсние сохраняется как г-значение р; «!) г-значение переменной р прсобразустжя в йзначение (*р), но это — 1-значение переменной ц следовательно, г-значение переменной т устанавливается равным 7. Ниже приведен болсс полный пример программы па языке бй еатп[) !тпт *р, *ц т.
)д 7* р и Π— у«азатели на целые *7 тпг *'цц 7* цц — указатель на указатель на целое *7 т=1. а=2; ргтптп "[=ХО: о'=тейп".7,1); 7* печатает [.З *7 р=а т; 7* р= 7-значение перененной т *7 о = а 2. 7* ц= 7-значение лерекенной З *7 *р =*ц. ргтптп "[=го: о=то лп".7.)): 7* то ие, что т = ) *7 ац = з р 7* цц указнвает на р *7 **Ос = 7, ршптИ"!=ХО; о=тедо",ты).) 7* то ие, что т = 7 *7 Вывод пз этой программы следующий: [-1; н-2: 1 2; й 2; [-7;,)-2; Оператор ввода, Большинство языков программирования включают операторную форму для чтения вводимых пользователем данных с терминала, из файлов или из линии связи. Эти операторы также изменяют значение переменных чсрсз операции присваивания. Обычно синтаксис таких операторов выглядит как геев[[ гт [е, [[ага).
В языке с вызов функции рш лгу приводит к записи файла в буферную переменную. В языке Рег! простое упоминание входного файла вызывает операцию чтения (например, ЪХ=.<570[И> вызывает присваивание переменной ЪХ очередной строки ввода). Другие операторы присваивания. Передача параметров (раздел 9.3) обычно определяется как присваивапие значения аргумента формальному параметру. Также в языках программирования можно найти различные формы неявного присваивания (например, в языке Я[ч[ОВО[А каждая ссылка на переменную!7[Р[[7 приводит к присваиванию этой переменной нового значения), а сопоставление с целью в языке Рго! ой (например, резолюция) также вызывает неявное присваив ание значений переменным.
Часто можно присвоить начальное значение переменной при се объявлении. Формы управления последовательностью действий на уровне операторов Обычно выделяют три формы управления последовательностью действий на уроннс операторов: 8.3. Управление последовательностью выполнения операторов 351 + Композиция. Операторы могут быть представлены в виде текстовой последовательности, так что всякий раз, когда выполняется большая программная структура, содержащая эту последовательность, операторы последовательности выполняются в надлежащем порядке.
+ Ветвление. Две последовательности операторов могут быть альтернативными, так что при выполнении большей программной структуры, содержащей обе эти последовательности, выполняется только одна из них, но не обе вместе. + Повторение. Последовательность операторов может выполняться неоднократно, О или более раз (ноль означает, что выполнение может быть вообще опущено), когда бы ни выполнялась большая программная структура, содержащая эту последовательность операторов. Для достижения желаемого эффекта при конструировании программы мы объединяем элементарные операторы, производящие вычисления, в определенные последовательности с помощью многократного использования композиции, ветвления и повторения.
Часто используются вариации каждой из этих основных форм управления, саответствуюгцие конкретной цели. Например, часто приходится выбирать из нескольких, а пе из двух вариантов последовательностей. Обычно в языке программирования предусматриваются различные структуры управления последовательностью действий, предназначенные для упрощения выражения подобных форм управления. Явное управление последовательностью операторов Ранние языки программирования разрабатывались для существовавпшх в то время конкретных вычислительных машин, на которых и предполагалось выполнять программы, написанные на этих языках.
Поскольку память машин представлялась в виде определенных областей, ранние языки (например, РОРзТКАН, АЕОО).) моделировали их с помощью простых типов данных, непосредственно переводимых в машинные объекты (например, тип переменных Поат языка С или геа1 в языке РОКТКАХ переводился в аппаратный тип с плавающей точкой, а тип афпг языка С вЂ” в аппаратный целочисленный тип), и простых операторов, состоящих из меток и ветвей. Передача управления чаще всего указывается с помощью цото— оператора перехода на оператор с заданной меткой. Во многих языках часто присутствует два вида оператора усто: + Безусловный оого. Если в последовательности опера~оров встречается оператор безусловного перехода дога, например: Осто ЬЕХТ то управление передается оператору, помеченному меткой ИЕХТ, а оператор, непосредственно следующий за оператором йото, не выполняешься.
+ Условный доге. Если в последовательности операторов встречается оператор условного перехода сего, например: Н А = О тяеп Ооьо ЗЕХТ то управление передается оператору, полгеченноему меткой ИЕХТ, только если выполняется заданное условие. 352 Глава 8. Управление последовательностью действий Хотя оператор до(о — вполне обычный оператор, за последние 30 лет ему пришлось пережить нелегкие времена. Его использование при написании программ подвергалось постоянной критике. Как будет показано ниже, оператор досо нарушает принцип структурного проектирования программы. Например, большая часть формального моделирования, приводящего к аксиоматически корректной модели разработки программы (раздел 4.2А), зависит от рациональной структуры управления для программы.
Фактически, используя аксиоматическую модель, описанную в упомянутом разделе, не так просто включить в арсенал разработки оператор додо. Более важно то, что, как было показано, оператор додо является ва самом деле излишним. (См. структурную теорему в этой же главе, раздел 8.3.3.) Любую программу можно написать без оператора досо, и при обучении языкам С или Рааса( большинству студентов даже не сообщают о его существовании в этих языках.
Оператор ЬгеаЬ. Некоторые языки, такие как С, включают оператор ЬгеаЬ как форму явного структурированного управления выполнением операторов. Обычно оператор Ьгей передает управление оператору, непосредственно следующему за структурой управления, в которой он сам содержится. Так, в языке С оператор ЬгеаЬ вызывает немедленный выход из операторов нП1!е, аког, зи1'ссП, в которых он встречается.
Использование оператора ЬгеаЬ продолжает порождать структуру управления с одним входом и одним выходом, которая позволяет разрабатывать формальные свойства программы (рис. 8.5). игьхе(в<Ь) (- гк И (воптеГП(пд) Ьгевх; Рис. 8.8. Структурный оператор Ьгввм е — синтаксис; б — выполнение оператора 8.3. Управление последовательностью выполнения операторов 353 Также язык С включает в себя родственный оператору Ьгеа~ оператор соп11 лое, который завершает выполнение текущей итерации цикла в операторах иЬП е и аког и переводит управление в конец тела цикла. Таким образом, оператор Ьгеа~ прерывает цикл, в то время как оператор соп11пце передает управление следующей итерации.
Однако использование оператора ЬгеЫ языка С (и связанного с ним оператора зи11сЬ) иногда является причиной нестабильной работы программ на С. Если нет оператора Ьгей, то от одного ключа оператора зн1 гсЬ управление переходит к следующему. Также может возникнуть путаница, из какой именно конструкции при наличии оператора Ьгезх следует выйти. В начале 60-х гг. в США произошел большой сбой в работе телефонной сети фактически из-за неправильного размещения оператора Ьгеа1. Парадигма структурного программирования Хотя в большинстве языков определены метки и операторы оосо, уже в 70-е гг.
имели место серьезные споры по поводу их применения. В некоторых новых языках (например, М1.) оператор його отсутствует. Перечисленные ниже недостатки использования оператора оого сильно перевешивают любое из его достоинств. Отсутствие иерархической структуры программы. Правильность работы программы гораздо важнее эффективности ее выполнения.
При разработке языка программирования должно выполняться это требование. Концепция управляющей структуры с одним входом и одним выходом обеспечивает более понятную структуру программы. В программе, состоящей из большого количества операторов, трудно разобраться, если нет иерархической организации операторов в группы, так чтобы каждая группа представляла собой один концептуальный элемент программы, Каждая из этих групп организуется как несколько подгрупп, использующих одну из форм управления и т.