приоритет операторов в C - PullRequest
       14

приоритет операторов в C

3 голосов
/ 21 декабря 2010

имеют проблемы с пониманием этого выражения:

(x + y - 1) / y * y

Приоритет операторов следующий (согласно моему пониманию и K & R2, 2.12, таблица 2.1):

1) оценить, что вparens: сначала (x + y), затем (x + y) -1

2) оператор '*' имеет более высокий приоритет, чем '/', поэтому он должен идти первым, но кажется, что (y* y) оценивается, а затем результат (x + y-1) делится на произведение (y * y).Я не совсем понимаю.

3) Я когда-либо слышал, чтобы это нормально округлялось в следующей форме:

(x + y - 1) / y * y

Это правильно?Заранее большое спасибо!

Ответы [ 6 ]

6 голосов
/ 21 декабря 2010

Унарный оператор * имеет более высокий приоритет, чем /, но для разыменования указателя.

Умножение * и деление / имеют одинаковый приоритет слева направо.

5 голосов
/ 21 декабря 2010

нет, * и / имеют одинаковый приоритет.(это называется " приоритет ", а не "приоритет")

(x + y - 1) / y * y

будет

( ( (x+y) - 1 ) / y ) * y

Дерево операций будет:

           *
          / \
         /   y
        ÷
       / \
      /   y
     -
    / \
   /   1
  +
 / \
x   y
4 голосов
/ 21 декабря 2010

Как упоминалось ранее, "*" и "/" имеют одинаковый приоритет, поэтому они оцениваются слева направо.Абсолютно однозначное выражение дает:

( ( ( (x + y) - 1) / y) * y)
2 голосов
/ 21 декабря 2010

1) вправо

2) Нет, "/" и "*" имеют одинаковый приоритет.Так что это будет выполнено слева направо.

3) Я не понимаю, что означает ваш «округление вверх».Но, например:

С y = 2, x = 2

(x + y -1) / y * y = (2 + 2 - 1) / 2 * 2 = (3/ 2) * 2 = 1 * 2 = 2

3/2 = 1, потому что это деление на целое число.

1 голос
/ 21 декабря 2010

'*' оператор имеет более высокий приоритет, чем '/'

Неправильно.И *, и / имеют равный приоритет и являются левоассоциативными.

После вычисления выражения в скобках имеем:

(x + y - 1) / y * y = z / y * y      // where z = x + y -1

                    = (z / y) * y    // because of associativity.
0 голосов
/ 21 декабря 2010

Я могу ошибаться, но насколько я помню / и * имеют такой же приоритет. Таким образом, результат должен быть (x + y + 1).

Может быть, вам следует сказать (x + y + 1) / (y * y), если вы хотите, чтобы результат был.

В любом случае, устранение неоднозначности никогда не стоит много.

Что касается использования ((x + y-1) / y) * y для округления в большую или меньшую сторону, в зависимости от обстоятельств, это сомнительная и не очень переносимая практика. Несколько причин: 1 / вы должны знать или помнить, что y - это своего рода int, 2 / x также должно быть своего рода int, 3 / результаты могут отличаться в зависимости от компилятора.

...