Выражения приоритеты операций в выражениях

Обновлено: 22.11.2024

Чтобы правильно вычислять выражения (например, 4 + 2 * 3 ), мы должны знать, что делают определенные операторы и в каком порядке они выполняются. Последовательность, в которой они выполняются, называется приоритетом операций. Следуя обычным правилам математики (в которой умножение следует перед сложением), выражение, приведенное выше, обрабатывается следующим образом: 4 + (2 * 3) = 10 .

В языке C++ все операторы (операции) имеют свой уровень приоритета. Те, в которых он выше, выполняются первыми. В таблице, приведенной ниже, можно увидеть, что приоритет операций умножения и деления (5) выше, чем в операциях сложения и вычитания (6). Компилятор использует приоритет операторов для определения порядка обработки выражений.

А что делать, если у двух операторов в выражении одинаковый уровень приоритета, и они размещены рядом? Какую операцию компилятор выполнит первой? А здесь уже компилятор будет использовать правила ассоциативности, которые указывают направление выполнения операций: слева направо или справа налево. Например, в выражении 3 * 4 / 2 операции умножения и деления имеют одинаковый уровень приоритета (5-й уровень). А ассоциативность пятого уровня соответствует выполнению операций слева направо, таким образом: (3 * 4) / 2 = 6 .

Оглавление:

Таблица приоритета и ассоциативности операций

Несколько примечаний:

1 означает самый высокий уровень приоритета, а 17 — самый низкий. Операции с более высоким уровнем приоритета выполняются первыми.

L -> R означает слева направо.

R -> L означает справа налево.

Побитовое НЕ (NOT)

Некоторые операторы вы уже знаете из предыдущих уроков: + , - , * , / , () , = , < и > . Их значения одинаковы как в математике, так и в языке C++.

Однако, если у вас нет опыта работы с другими языками программирования, то большинство из этих операторов вам сейчас могут быть непонятны. Это нормально. Мы рассмотрим большую их часть на уроках этой главы, а об остальных расскажем по мере необходимости.

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

Как возвести число в степень в C++?

Вы уже должны были заметить, что оператор ^ , который обычно используется для обозначения операции возведения в степень в обычной математике, не является таковым в языке C++. В языке С++ это побитовая операция XOR. А для возведения числа в степень в языке C++ используется функция pow(), которая находится в заголовочном файле cmath:

double x = pow ( 3.0 , 4.0 ) ; // 3 в степени 4

Обратите внимание, параметры и возвращаемые значения функции pow() являются типа double. А поскольку типы с плавающей точкой известны ошибками округления, то результаты pow() могут быть неточными (чуть меньше или чуть больше).

Если вам нужно возвести в степень целое число, то лучше использовать собственную функцию, например:

// Примечание: Экспонент не должен быть отрицательным int pow ( int base , int exp ) int result = 1 ; while ( exp ) if ( exp & 1 ) result * = base ; exp >> = 1 ; base * = base ; return result ;

Не переживайте, если здесь что-то не понятно. Просто помните о проблеме переполнения, которая может произойти, если один из аргументов будет слишком большим.

Из школьной математики нам известно, что выражения внутри скобок выполняются первыми. Например, в выражении (2 + 3) * 4 часть (2 + 3) выполняется первой.

В этом задании есть 4 выражения, в которых отсутствуют какие-либо скобки. Используя приоритет операций и правила ассоциативности, приведенные выше, добавьте скобки в каждое выражение так, как если бы их обрабатывал компилятор.

Например: х = 2 + 3 % 4

Бинарный оператор % имеет более высокий приоритет, чем оператор + или = , поэтому он выполняется первым: х = 2 + (3 % 4) . Затем выполняется бинарный оператор + , так как он имеет более высокий приоритет, чем оператор = .

Ответ: х = (2 + (3 % 4)) .

Дальше нам уже не нужна таблица, чтобы понять ход обработки этого выражения компилятором.

Задания:

Выражение №1: x = 3 + 4 + 5

Выражение №2: x = y = z

Выражение №3: z *= ++y + 5

Ответ

Выражение №1: x = 3 + 4 + 5

Уровень приоритета бинарного оператора + выше, чем оператора = , поэтому: х = (3 + 4 + 5) . Ассоциативность бинарного оператора + слева направо, поэтому ответ: х = ((3 + 4) + 5) .

Выражение №2: x = y = z

Ассоциативность бинарного оператора = справа налево, поэтому ответ: x = (y = z) .

Выражение №3: z *= ++y + 5

Унарный оператор ++ имеет наивысший приоритет, поэтому: z *= (++y) + 5 . Затем идет бинарный оператор + , поэтому ответ: z *= ((++y) + 5) .

Выражение №4: a || b && c || d

Бинарный оператор && имеет приоритет выше, чем || , поэтому: a || (b && c) || d . Ассоциативность бинарного оператора || слева направо, поэтому ответ: (a || (b && c)) || d .

(380 оценок, среднее: 4,90 из 5)
Загрузка.

Глава №2. Итоговый тест

Урок №39. Арифметические операторы

Комментариев: 15

Виктор :

Чё-то нифига не понятно.
while (exp)
1. exp==false(0), цикл не выполняется и сразу return. Тут понятно.
2. exp==true(1), то получаем бесконечный цикл. Не увидел условие выхода из цикла.
3. exp==2, 3 и т.д , то есть при другом возможном значении?

AHTOH :

Если выражение exp >>= 1; вызывать много раз то оно в любом случае, когда то станет 0 т.е. FALSE. Но до тех пор пока оно не 0 оно TRUE.

Богдан :

Это так называемое "быстрое возведение в степень". Его ещё называют RPA(russian peasant algorithm(или алгоритм русского крестьянина)). На данном примере выигрыш во времени около нулевой, а вот если бы мы писали длинную арифметику, то там бы это нам серьёзно помогло.

Георгий :

«Если вам нужно возвести в степень целое число, то лучше использовать собственную функцию»
Что-то я не понял, а зачем нам pow() тогда вообще? Нам привели пример как пользоваться pow, но сказали использовать какой то не понятный вариант. Вообще ничего не понял в этой главе с возведением в степень. Можно объяснить? Почему мы не можем возвести в степень целочисленный тип через pow()? Если через double лучше не делать, то зачем pow()?

PP189 :

Использование собственной функции нужно для возведения целых чисел в степень. Например, степени десятки для перевода в различные системы счисления.
Pow() применяется для чисел с плавающей точкой: он может принять аргументы int, но вернет их в возможно не точном виде типа double. При этом, даже такое неточное значение может пригодиться в математических уравнениях.

Борис : Андрей :

Возвести целое число в целую степень разве не проще через обычный цикл?

int pow2 ( int base , int exp ) < int result = 1 ; for ( int i = 0 ; i < exp ; i ++ ) < result * = base ; return result ;

Зачем такая витиеватость?

Андрей :

Понятно. Количество умножений сократили.

AHTOH :

Количество умножений не может сократится. Иначе будет не верный результат. Сдается мне что если дисасемблировать ваш вариант и тот что в уроке, они будут практически одинаковыми.
И скорость схожения у них одинаковая.

Xakim :

Пример. база 10, степень 20. В уроке степень считается битами, 20 это 10100, пять умножений плюс ещё два умножения на единичках, в цикле 20. Худший вариант это пять единиц(степень 31), тогда в урочном примере 10 умножений, а комментовом 31.
Для степеней больше 31 количество умножений ещё больше различается, а на малых числах одинакова.
Или я не так что-то понял?

Bogdan Steh : zashiki : Chestor :

<< и >> это всё те же операции битового сдвига влева и вправо соответсвенно, НО, в пространстве имён std эти две операции ПЕРЕОПРЕДЕЛЕНЫ. Думаю, о переопределении, речь пойдёт в след. уроках и Вы узнаете, что это такое. Но можете сейчас погуглить )))

Читайте также: