2.12. Старшинство и порядок вычисления.
В приводимой ниже таблице сведены правила старшинства и ас-
социативности всех операций, включая и те, которые мы еще не
обсуждали. Операции, расположенные в одной строке, имеют
один и тот же уровень старшинства; строки расположены в по-
рядке убывания старшинства. Так, например, операции *, / и %
имеют одинаковый уровень старшинства, который выше, чем уро-
вень операций + и -.
OPERATOR ASSOCIATIVITY
() [] -> . LEFT TO RIGHT
! \^ ++ -- - (TYPE) * & SIZEOF RIGHT TO LEFT
* / % LEFT TO RIGHT
+ - LEFT TO RIGHT
<< >> LEFT TO RIGHT
< <= > >= LEFT TO RIGHT
· 57 -
== != LEFT TO RIGHT
& LEFT TO RIGHT
^ LEFT TO RIGHT
\! LEFT TO RIGHT
&& LEFT TO RIGHT
\!\! LEFT TO RIGHT
?: RIGHT TO LEFT
= += -= ETC. RIGHT TO LEFT
, (CHAPTER 3) LEFT TO RIGHT
Операции -> и . Используются для доступа к элементам струк-
тур; они будут описаны в главе 6 вместе с SIZEOF (размер
объекта). В главе 5 обсуждаются операции * (косвенная адре-
сация) и & (адрес).
Отметим, что уровень старшинства побитовых логических опера-
ций &, ^ и э ниже уровня операций == и !=. Это приводит к
тому, что осуществляющие побитовую проверку выражения, по-
добные
IF ((X & MASK) == 0) ...
Для получения правильных результатов должны заключаться в
круглые скобки.
Как уже отмечалось ранее, выражения, в которые входит
одна из ассоциативных и коммутативных операций (*, +, &, ^,
э), могут перегруппировываться, даже если они заключены в
круглые скобки. В большинстве случаев это не приводит к ка-
ким бы то ни было расхождениям; в ситуациях, где такие рас-
хождения все же возможны, для обеспечения нужного порядка
вычислений можно использовать явные промежуточные перемен-
ные.
В языке “C”, как и в большинстве языков, не фиксируется
порядок вычисления операндов в операторе. Например в опера-
торе вида
X = F() + G();
сначала может быть вычислено F, а потом G, и наоборот; поэ-
тому, если либо F, либо G изменяют внешнюю переменную, от
которой зависит другой операнд, то значение X может зависеть
от порядка вычислений. Для обеспечения нужной последователь-
ности промежуточные результаты можно опять запоминать во
временных переменных.
Подобным же образом не фиксируется порядок вычисления
аргументов функции, так что оператор
PRINTF(“%D %D\N”,++N,POWER(2,N));
·
58 -
может давать (и действительно дает) на разных машинах разные
результаты в зависимости от того, увеличивается ли N до или
после обращения к функции POWER. Правильным решением, конеч-
но, является запись
++N;
PRINTF(“%D %D\N”,N,POWER(2,N));
Обращения к функциям, вложенные операции присваивания,
операции увеличения и уменьшения приводят к так называемым
“побочным эффектам” - некоторые переменные изменяются как
побочный результат вычисления выражений. В любом выражении,
в котором возникают побочные эффекты, могут существовать
очень тонкие зависимости от порядка, в котором определяются
входящие в него переменные. примером типичной неудачной си-
туации является оператор
A[I] = I++;
Возникает вопрос, старое или новое значение I служит в ка-
честве индекса. Компилятор может поступать разными способами
и в зависимости от своей интерпретации выдавать разные ре-
зультаты. Тот случай, когда происходят побочные эффекты
(присваивание фактическим переменным), - оставляется на ус-
мотрение компилятора, так как наилучший порядок сильно зави-
сит от архитектуры машины.
Из этих рассуждений вытекает такая мораль: написание
программ, зависящих от порядка вычислений, является плохим
методом программирования на любом языке. Конечно, необходимо
знать, чего следует избегать, но если вы не в курсе, как не-
которые вещи реализованы на разных машинах, это неведение
может предохранить вас от неприятностей. (Отладочная прог-
рамма LINT укажет большинство мест, зависящих от порядка вы-
числений.
· 59 -
3. Поток управления
Управляющие операторы языка определяют порядок вычисле-
ний. В приведенных ранее примерах мы уже встречались с наи-
более употребительными управляющими конструкциями языка “C”;
здесь мы опишем остальные операторы управления и уточним
действия операторов, обсуждавшихся ранее.
... основаниям. При этом философская абстракция языка оказывается неразрывно связана с основными темами и движениями философии в целом. Более конкретно, на ранние стадии традиционно рассматриваемого в рамках АФ анализа обыденного языка глубокое влияние оказала философия Дж. Э. Мура, особенно его учение о здравом смысле, согласно которому такие понятия, как «человек», «мир», «я», «внешний мир», « ...
... и других странах СНГ, а также облегчение доступа к русской и мировой культуре и науке. Таким образом, судя по данным наших исследований, востребованность русского языка осталась в республике достаточно высокой. Многие представители современной молдавской молодежи продолжают, как их отцы и деды, тянуться к русской культуре, научным и техническим достижениям России. Русский язык остается языком ...
... рисуночное словесно-слоговое письмо). Памятники среднеэламского периода (14—12 вв. до н.э.) выполнены аккадской клинописью. Памятники новоэламского периода относятся к 8—6 вв. до н.э. Был официальным языком в персидском государстве Ахеменидов в 6—4 вв. предполагается, что он, подвергшись влиянию древнеперсидского, сохранился до раннего средневековья. 7. Бурушаски язык Язык бурушаски ( ...
... /диалект), скифский, согдийский, среднеперсидский, таджикский, таджриши (язык/диалект), талышский, татский, хорезмийский, хотаносакский, шугнано-рушанская группа языков, ягнобский, язгулямский и др. Они относятся к индоиранской ветви индоевропейских языков. Области распространения: Иран, Афганистан, Таджикистан, некоторые районы Ирака, Турции, Пакистана, Индии, Грузии, Российской Федерации. Общее ...
0 комментариев