В эту эпоху, когда люди часто просто говорят о модных словах AI, ML, Data Science, Big Data и т. Д., Я чувствовал необходимость прояснить ситуацию в отношении чего-то очень наивного, но часто неправильно понимаемого и неправильно интерпретируемого. В области программирования детские шаги начинаются с манипулирования данными в форме выражений с помощью операторов. А вот и часть, которую легко, но удивительно неверно истолковать.

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

Позвольте мне сначала определить термины.

Интерпретация выражения, содержащего более одного оператора, часто не совсем понятна. Например, означает ли a + b * c «сложить a и b, затем умножить результат на c», или это означает «умножить b и c, затем добавить a»? Поэтому создатели решили навести порядок в приоритете операторов, который очень похож на реальные расчеты. Приоритет операторов помогает нам определить, как компилятор интерпретирует выражения. Это просто позволяет нам понять, что если к операнду примыкает более одного оператора, то к какому оператору принадлежит этот операнд. Проще говоря, будет ли приведенное выше выражение обрабатываться как (a + b) * c или a + (b * c), если мы все знаем, что делают круглые скобки. Что делать, если некоторые операторы имеют одинаковый приоритет и когда выражение содержит два или более таких оператора.

В этой ситуации вступает в игру ассоциативность оператора. В C оператор левоассоциативен, если группируется слева направо. Например, все бинарные арифметические операторы левоассоциативны. a- b + c эквивалентно (a-b) + c, поскольку оба + и - имеют одинаковый приоритет, аналогично a * b / c эквивалентно (a * b) / c. Оператор является правоассоциативным, если группируется справа налево. Оператор присваивания, унарные арифметические операторы являются правоассоциативными. a = b = c рассматривается как a = (b = c), а - + a рассматривается как - (+ a). Теперь животрепещущий вопрос: говорят ли эти правила нам, как выражение оценивается и выполняется внутри машины? Конечно нет.

Выполнение зависит от компьютерной системы, компиляторов, операционной системы и многих других факторов. Мы можем разбить любое выражение C на подвыражение с соблюдением правил приоритета операторов и ассоциативности. Это помогает нам заключать выражение в круглые скобки. НО помните тот факт, что эти правила не всегда позволяют нам определять значение выражений, которые зависят от порядка, в котором оцениваются его подвыражения, и чаще всего такие языки, как C, не определяют порядок, в котором оцениваются подвыражения ( за исключением некоторых операторов).

И, следовательно, в выражении вроде (p + q) * (r + s) мы не знаем, что я хочу подчеркнуть, что МЫ НЕ ЗНАЕМ, будет ли (p + q) вычисляться до (r + s) или наоборот. наоборот.

Зачем столько суетиться из-за такой банальной вещи? Причина в том, что индийская система образования и найма одержима вопросами, на которые нет однозначного ответа, если только мы не предполагаем каких-то конкретных вещей. Например, вы найдете множество вопросов, таких как a = 5; printf («% d% d% d», a ++, ++ a, a ++); И здесь люди даже ответят на нелогичные утверждения, например, printf оценивает слева направо или наоборот. Такие вещи вообще не определены и считаются неопределенным поведением. Такие авторы, как Деннис Ричи, Бьярн Страуструп и другие, полностью прояснили это. Итак, вопросы вроде c = (b = a + 2) - (a = 1); не имеют никакого смысла, пока не появится опция, указывающая, что это не определено.

Часто интерес представляет решение задач, в которых значение переменной используется и изменяется одновременно. Например, i = i + i ++; Следует избегать этого типа операторов, поскольку порядок работы не определен в стандарте языка. Переходя к таким вопросам, как i = i ++; часто удобно думать, что по крайней мере значение i будет увеличено после выполнения этого оператора. Но снова это не определено, и я могу объяснить вам причину, по которой в некоторых компиляторах (или в большинстве) он вообще не увеличивается, но для этого потребуется целая другая статья или редактирование этой.

Надеюсь, это немного прояснит. Я подпишусь сейчас, оставив вам несколько фрагментов и ссылку на некоторые вопросы по этому поводу.