Выражения приоритеты операций в выражениях
Обновлено: 22.12.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 означает справа налево.
Некоторые операторы вы уже знаете из предыдущих уроков: + , - , * , / , () , = , < и > . Их значения одинаковы как в математике, так и в языке 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 и т.д , то есть при другом возможном значении?
Если выражение exp >>= 1; вызывать много раз то оно в любом случае, когда то станет 0 т.е. FALSE. Но до тех пор пока оно не 0 оно TRUE.
Богдан :Это так называемое "быстрое возведение в степень". Его ещё называют RPA(russian peasant algorithm(или алгоритм русского крестьянина)). На данном примере выигрыш во времени около нулевой, а вот если бы мы писали длинную арифметику, то там бы это нам серьёзно помогло.
Георгий :«Если вам нужно возвести в степень целое число, то лучше использовать собственную функцию»
Что-то я не понял, а зачем нам pow() тогда вообще? Нам привели пример как пользоваться pow, но сказали использовать какой то не понятный вариант. Вообще ничего не понял в этой главе с возведением в степень. Можно объяснить? Почему мы не можем возвести в степень целочисленный тип через pow()? Если через double лучше не делать, то зачем pow()?
Использование собственной функции нужно для возведения целых чисел в степень. Например, степени десятки для перевода в различные системы счисления.
Pow() применяется для чисел с плавающей точкой: он может принять аргументы int, но вернет их в возможно не точном виде типа double. При этом, даже такое неточное значение может пригодиться в математических уравнениях.
Возвести целое число в целую степень разве не проще через обычный цикл?
int pow2 ( int base , int exp ) < int result = 1 ; for ( int i = 0 ; i < exp ; i ++ ) < result * = base ; return result ;Зачем такая витиеватость?
Андрей :Понятно. Количество умножений сократили.
AHTOH :Количество умножений не может сократится. Иначе будет не верный результат. Сдается мне что если дисасемблировать ваш вариант и тот что в уроке, они будут практически одинаковыми.
И скорость схожения у них одинаковая.
Пример. база 10, степень 20. В уроке степень считается битами, 20 это 10100, пять умножений плюс ещё два умножения на единичках, в цикле 20. Худший вариант это пять единиц(степень 31), тогда в урочном примере 10 умножений, а комментовом 31.
Для степеней больше 31 количество умножений ещё больше различается, а на малых числах одинакова.
Или я не так что-то понял?
<< и >> это всё те же операции битового сдвига влева и вправо соответсвенно, НО, в пространстве имён std эти две операции ПЕРЕОПРЕДЕЛЕНЫ. Думаю, о переопределении, речь пойдёт в след. уроках и Вы узнаете, что это такое. Но можете сейчас погуглить )))
Читайте также: