Как приоритет операторов влияет на порядок оценки? [дубликат] ⇐ C++
Как приоритет операторов влияет на порядок оценки? [дубликат]
Как приоритет операторов влияет на порядок вычислений, а не на разницу между ними? Чтобы лучше проиллюстрировать свой вопрос, ниже я приведу краткое объяснение приоритета операторов.
Следующий код предназначен только для демонстрационных целей. Подумайте:
int i=++a*b+c/d/e В некоторых объяснениях будет сказано, что из-за приоритета операторов * и / будут выполняться перед +, но мне нравится думать об этом следующим образом: если два оператора с разным приоритетом борются за одно и то же выражение, то тот, у которого более высокий приоритет получает выражение и формирует новое выражение с ним и его операндами. Таким образом, верхний пример на самом деле:
int i=((++a)*b)+((c/d)/e) Это известно во время компиляции. Во время выполнения запускается порядок оценки, и он решает, будет ли сначала оцениваться a,b,c,d или i. Какое выражение вычисляется первым, определяется путем секвенирования, хотя большинство операторов не имеют последовательности или имеют неопределенную последовательность.
Причина, по которой в C++ используются неупорядоченные операторы вместо, скажем, строгого правила последовательности слева направо, заключается в том, что они предоставляют больше возможностей для оптимизации (например, операции могут перекрываться и чередоваться), а наличие более строгих правил последовательности может отрицательно сказаться на производительности программы. . Существует два отдельных набора правил для расчета значений и побочных эффектов соответственно. (1)
Поэтому необходимо сделать одно важное различие — это различие между вычислением значения и побочными эффектами. Последовательность вычислений значений всегда определяется приоритетом операторов и ассоциативностью.
Вычисления значений (но не побочные эффекты) операндов любого оператора выполняются перед вычислением значения результата оператора (но не его побочных эффектов).
На примере примера это означает, что значение выражений (++a) и b должно быть вычислено до (++a)*b , так как без знания a или b невозможно вычислить их произведение, а это означает, что для вычислений значений приоритет операторов напрямую влияет на порядок вычисления. .
Таким образом, в программе C++, состоящей исключительно из вычислений значений, порядок вычислений будет полностью определяться приоритетом операторов и ассоциативностью.(2)
Каждый раз, когда я объясняю это таким образом, у меня всегда возникает вопрос, если бы не было указано, в каком порядке выражения c,d и e в ((c/d)/e ) оцениваются, как приоритет операторов определяет порядок вычислений? На что я всегда отвечаю, что без побочных эффектов порядок вычисления операндов не имеет значения, если они оцениваются до вычисления значения результата оператора. (3)
Однако это не относится к побочным эффектам. a++ имеет побочный эффект: значение, хранящееся в a, увеличивается на 1. Поскольку побочные эффекты обычно не упорядочиваются по приоритету операторов, это означает, что приращение в >++a может произойти до, во время или после умножения (++a)*b. Черт возьми, это может произойти даже после вычисления значения всего выражения прямо с помощью оператора присваивания ((++a)*b)+((c/d)/e).
Таким образом, именно побочные эффекты могут вызвать неопределенное поведение при неправильной последовательности. Без побочных эффектов можно иметь столько вычислений значений, расположенных рядом друг с другом, сколько захотите. (4)
В выражении ((c/d)/e), если c,d или e имеют побочные эффекты (например, если они были функциями, изменяющими глобальные значения) тогда действительно имеет значение, в каком порядке они оцениваются, даже если они оцениваются до вычисления значения результата оператора.
Основной вывод заключается в том, что всякий раз, когда кто-то говорит о разнице между порядком оценки и приоритетом операторов, на самом деле они имеют в виду «последовательность вычислений значений и последовательность побочных эффектов».
Для меня различие между вычислением значения и побочным эффектом важно для понимания разницы между порядком вычисления и правильным приоритетом операторов. Я всегда объяснял это именно так, однако, просматривая множество объяснений в Интернете, большинство из них даже не упоминают об этой разнице, используя утверждения типа «Они связаны, но различны».
Это сбивает с толку, поскольку порядок вычисления значений очень тесно связан с приоритет оператора. Это вычисление побочного эффекта, не зависящее от приоритета оператора.
Это оставляет у меня некоторые сомнения в моем понимании:
Правильно ли мое объяснение выше?
Я хочу конкретно сосредоточиться на параграфах (1), (2), (3) и (4).
Как приоритет операторов влияет на порядок вычислений, а не на разницу между ними? Чтобы лучше проиллюстрировать свой вопрос, ниже я приведу краткое объяснение приоритета операторов.
Следующий код предназначен только для демонстрационных целей. Подумайте:
int i=++a*b+c/d/e В некоторых объяснениях будет сказано, что из-за приоритета операторов * и / будут выполняться перед +, но мне нравится думать об этом следующим образом: если два оператора с разным приоритетом борются за одно и то же выражение, то тот, у которого более высокий приоритет получает выражение и формирует новое выражение с ним и его операндами. Таким образом, верхний пример на самом деле:
int i=((++a)*b)+((c/d)/e) Это известно во время компиляции. Во время выполнения запускается порядок оценки, и он решает, будет ли сначала оцениваться a,b,c,d или i. Какое выражение вычисляется первым, определяется путем секвенирования, хотя большинство операторов не имеют последовательности или имеют неопределенную последовательность.
Причина, по которой в C++ используются неупорядоченные операторы вместо, скажем, строгого правила последовательности слева направо, заключается в том, что они предоставляют больше возможностей для оптимизации (например, операции могут перекрываться и чередоваться), а наличие более строгих правил последовательности может отрицательно сказаться на производительности программы. . Существует два отдельных набора правил для расчета значений и побочных эффектов соответственно. (1)
Поэтому необходимо сделать одно важное различие — это различие между вычислением значения и побочными эффектами. Последовательность вычислений значений всегда определяется приоритетом операторов и ассоциативностью.
Вычисления значений (но не побочные эффекты) операндов любого оператора выполняются перед вычислением значения результата оператора (но не его побочных эффектов).
На примере примера это означает, что значение выражений (++a) и b должно быть вычислено до (++a)*b , так как без знания a или b невозможно вычислить их произведение, а это означает, что для вычислений значений приоритет операторов напрямую влияет на порядок вычисления. .
Таким образом, в программе C++, состоящей исключительно из вычислений значений, порядок вычислений будет полностью определяться приоритетом операторов и ассоциативностью.(2)
Каждый раз, когда я объясняю это таким образом, у меня всегда возникает вопрос, если бы не было указано, в каком порядке выражения c,d и e в ((c/d)/e ) оцениваются, как приоритет операторов определяет порядок вычислений? На что я всегда отвечаю, что без побочных эффектов порядок вычисления операндов не имеет значения, если они оцениваются до вычисления значения результата оператора. (3)
Однако это не относится к побочным эффектам. a++ имеет побочный эффект: значение, хранящееся в a, увеличивается на 1. Поскольку побочные эффекты обычно не упорядочиваются по приоритету операторов, это означает, что приращение в >++a может произойти до, во время или после умножения (++a)*b. Черт возьми, это может произойти даже после вычисления значения всего выражения прямо с помощью оператора присваивания ((++a)*b)+((c/d)/e).
Таким образом, именно побочные эффекты могут вызвать неопределенное поведение при неправильной последовательности. Без побочных эффектов можно иметь столько вычислений значений, расположенных рядом друг с другом, сколько захотите. (4)
В выражении ((c/d)/e), если c,d или e имеют побочные эффекты (например, если они были функциями, изменяющими глобальные значения) тогда действительно имеет значение, в каком порядке они оцениваются, даже если они оцениваются до вычисления значения результата оператора.
Основной вывод заключается в том, что всякий раз, когда кто-то говорит о разнице между порядком оценки и приоритетом операторов, на самом деле они имеют в виду «последовательность вычислений значений и последовательность побочных эффектов».
Для меня различие между вычислением значения и побочным эффектом важно для понимания разницы между порядком вычисления и правильным приоритетом операторов. Я всегда объяснял это именно так, однако, просматривая множество объяснений в Интернете, большинство из них даже не упоминают об этой разнице, используя утверждения типа «Они связаны, но различны».
Это сбивает с толку, поскольку порядок вычисления значений очень тесно связан с приоритет оператора. Это вычисление побочного эффекта, не зависящее от приоритета оператора.
Это оставляет у меня некоторые сомнения в моем понимании:
Правильно ли мое объяснение выше?
Я хочу конкретно сосредоточиться на параграфах (1), (2), (3) и (4).
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Объясните, как здесь, в этом Java-коде, работает приоритет операторов [дубликат]
Anonymous » » в форуме JAVA - 0 Ответы
- 12 Просмотры
-
Последнее сообщение Anonymous
-
-
-
Именно почему это работает таким образом? (Приоритет нулевого объединения) приоритет)
Anonymous » » в форуме Php - 0 Ответы
- 2 Просмотры
-
Последнее сообщение Anonymous
-
-
-
Общий термин, обозначающий как приоритет операторов, так и ассоциативность?
Anonymous » » в форуме C++ - 0 Ответы
- 10 Просмотры
-
Последнее сообщение Anonymous
-
-
-
Общий термин, обозначающий как приоритет операторов, так и ассоциативность?
Anonymous » » в форуме C++ - 0 Ответы
- 7 Просмотры
-
Последнее сообщение Anonymous
-