Приоритет оператора по сравнению с порядком оценки

Термины «приоритет оператора» и «порядок оценки» - очень часто используемые термины в программировании и чрезвычайно важные для программиста. И, насколько я понимаю, эти две концепции тесно связаны; одно невозможно обойтись без другого, когда речь идет о выражениях.

Возьмем простой пример:

int a=1;  // Line 1
a = a++ + ++a;  // Line 2
printf("%d",a);  // Line 3

Теперь очевидно, что Строка 2 ведет к Неопределенному поведению, поскольку Пункты последовательности в C и C ++ включают:

  1. Между вычислением левого и правого операндов && (логический очень часто используются в программировании и чрезвычайно важны для программиста. И, насколько я понимаю, эти два ...

    Термины «приоритет оператора» и «порядок оценки» - очень часто используемые термины в программировании и чрезвычайно важные для программиста. И, насколько я понимаю, эти две концепции тесно связаны; одно невозможно обойтись без другого, когда речь идет о выражениях.

    Возьмем простой пример:

    int a=1;  // Line 1
    a = a++ + ++a;  // Line 2
    printf("%d",a);  // Line 3
    

    Теперь очевидно, что Строка 2 ведет к Неопределенному поведению, поскольку Пункты последовательности в C и C ++ включают:

    1. Между вычислением левого и правого операндов && (логический очень часто используются в программировании и чрезвычайно важны для программиста. И, насколько я понимаю, эти два ...

      Термины «приоритет оператора» и «порядок оценки» - очень часто используемые термины в программировании и чрезвычайно важные для программиста. И, насколько я понимаю, эти две концепции тесно связаны; одно невозможно обойтись без другого, когда речь идет о выражениях.

      Возьмем простой пример:

      int a=1;  // Line 1
      a = a++ + ++a;  // Line 2
      printf("%d",a);  // Line 3
      

      Теперь очевидно, что Строка 2 ведет к Неопределенному поведению, поскольку Пункты последовательности в C и C ++ включают:

      1. Между вычислением левого и правого операндов && (логический и «порядок оценки» - очень часто используемые термины в программировании, которые чрезвычайно важны для программиста. И, насколько я понимаю, эти две концепции тесно связаны; одно невозможно обойтись без другого, когда речь идет о выражениях.

        Возьмем простой пример:

        int a=1;  // Line 1
        a = a++ + ++a;  // Line 2
        printf("%d",a);  // Line 3
        

        Теперь очевидно, что Строка 2 ведет к Неопределенному поведению, поскольку Пункты последовательности в C и C ++ включают:

        1. Между вычислением левого и правого операндов && (логический и «порядок оценки» - это очень часто используемые термины в программировании, которые чрезвычайно важны для программиста. И, насколько я понимаю, эти две концепции тесно связаны; одно невозможно обойтись без другого, когда речь идет о выражениях.

          Возьмем простой пример:

          int a=1;  // Line 1
          a = a++ + ++a;  // Line 2
          printf("%d",a);  // Line 3
          

          Теперь очевидно, что Строка 2 ведет к Неопределенному поведению, поскольку Пункты последовательности в C и C ++ включают:

          1. Между вычислением левого и правого операндов && (логический И), || (логическое ИЛИ) и запятая операторы. Например, в выражение * p ++! = 0 && * q ++! = 0 , все побочные эффекты подвыражения * p ++! = 0 завершаются перед любой попыткой доступа к q .

          2. Между вычислением первого операнда троичного оператор "знак вопроса" и второй или третий операнд. Например, в выражении a = (* p ++)? (* p ++) : 0 после первый * p ++ , что означает, что он уже увеличивается к тому времени, когда выполняется второй экземпляр.

          3. В конце полного выражения. Эта категория включает выражение заявления (например, присвоение a = b; ), операторы возврата, управляющие выражения if, switch, операторы while или do-while, и все три выражения в операторе for.

          4. Перед вводом функции в вызове функции. Порядок, в котором аргументы оцениваются не указано, но эта точка последовательности означает, что все их побочные эффекты завершаются до того, как функция поступил. В выражении f (i ++) + g (j ++) + h (k ++) , f вызывается с параметр исходного значения i , но i увеличивается до ввода корпус f . Аналогично, j и k являются обновлено перед вводом g и h соответственно. Однако это не так указано, в каком порядке f () , g () , h () выполняются, ни в каком порядке i , j , k увеличиваются. Значения j и k в теле f поэтому undefined. 3 Обратите внимание, что функция call f (a, b, c) не является использованием оператор запятой и порядок оценка для a , b и c является не указано.

          5. При возврате функции, после того, как возвращаемое значение копируется в контекст вызова. (Эта точка последовательности указывается только в стандарте C ++; он присутствует только неявно в C.)

          6. В конце инициализатора; например, после оценки 5 в объявлении int a = 5; .

          Таким образом, переходя по пункту № 3:

          В конце полного выражения. В эту категорию входят операторы выражений (например, присвоение a = b;), операторы return, управляющие выражения операторов if, switch, while или do-while, а также все три выражения в операторе for.

          Строка 2 явно приводит к неопределенному поведению. Это показывает, как Неопределенное поведение тесно связано с точками последовательности .

          Давайте рассмотрим другой пример:

          int x=10,y=1,z=2; // Line 4
          int result = x

          Теперь очевидно, что Строка 5 будет сделать переменную результат сохранить 1 .

          Теперь выражение x в Строке 5 можно вычислить как :

          x или (x . В первом случае значение результата будет 0 , а во втором случае результат будет 1 . Но мы знаем, когда Приоритет операторов равен Равно / То же - В игру вступает ассоциативность , следовательно, она оценивается как (x .

          Это то, что сказано в этой статье MSDN :

          Приоритет и ассоциативность операторов C влияют на группировку и оценку операндов в выражениях. Приоритет оператора имеет значение, только если присутствуют другие операторы с более высоким или более низким приоритетом. Сначала оцениваются выражения с операторами с более высоким приоритетом. Приоритет также можно описать словом «привязка». Операторы с более высоким приоритетом имеют более жесткую привязку.

          Теперь о вышеупомянутой статье:

          В ней упоминается «Сначала оцениваются выражения с операторами с более высоким приоритетом»

          Это может звучать неверно. Но я думаю, что в статье не говорится что-то неправильное, если учесть, что () также является оператором x то же самое, что (x . Я считаю, что если ассоциативность не играет роли, то полная оценка выражений станет неоднозначной, поскольку не является точкой последовательности .

          Кроме того, еще одна ссылка, которую я нашел, говорит об этом на Приоритет и ассоциативность операторов :

          На этой странице перечислены операторы C в порядке их приоритета (от высшего к низшему). Их ассоциативность указывает, в каком порядке применяются операторы равного приоритета в выражении.

          Итак, принимая, второй пример int result = x , мы можем видеть здесь, что есть во всех 3 выражениях, x , y и z , поскольку простейшая форма выражения состоит из единственной литеральной константы или объекта. Следовательно, результат выражений x , y , z будет там rvalues ​​, то есть 10 , 1 и 2 соответственно. Следовательно, теперь мы можем интерпретировать x как 10 .

          Разве ассоциативность не вступает в игру, поскольку теперь у нас есть 2 выражения, которые нужно оценить, либо 10 , либо 1 , и поскольку приоритет оператора такой же , имеют место, кроме случаев, указанных для вызова функции (), &&, ||,?: и запятой операторы (6.5).

          Теперь я хотел бы знать, было бы неправильно сказать:

          Порядок оценки зависит от приоритета операторов, оставляя случаи неопределенного поведения.

          Я хотел бы исправить если были допущены ошибки в том, что я сказал в своем вопросе. Причина, по которой я разместил этот вопрос, заключается в путанице, созданной в моей голове статьей MSDN. Это в Ошибка или нет?

44
задан Jonathan Leffler 20 April 2017 в 14:40
поделиться