Оператор предшествования
Есть одна «заморочка» в использовании встроенных операторов - при комбинации нескольких операторов в одном выражении порядок выполнения операций определяется предустановленным уровнем приоритетности для каждого. Например, результат выражения 5 + 2*10 всегда равен 25 и никогда 70, поскольку оператор умножения имеет больший приоритет, чем оператор сложения. В итоге 2 всегда умножается на 10 прежде, чем складывается с 5. ^
Мы можем переопределить приоритет, взяв в скобки операцию, с выполнения которой хотели бы начать. (5 + 2) * 10, например, принимает значение 70.
Для операторов, о которых я говорил, предопределенные уровни приоритетности написаны ниже. Оператор, который выше, имеет больший приоритет, чем тот, что ниже. Операторы, расположенные в одну линию, имеют порядок определения слева направо.
Логическое NOT арифметическое (*, /, %) арифметическое(+, -) отношение (<, >, <=, >=) отношение (= =, !=) логическое AND логическое OR присваивание
Например, для определения четности ival мы можем написать:
! ival % 2 // не совсем хорошо
Наше выражение проверяет результат оператора остатка. Если ival четно, результат нулевой и логический оператор НЕ становится истинным. Иначе, если результат ненулевой, логический оператор НЕ принимает значение false. Во всяком случае, так нам хотелось бы.
К сожалению, результат выражения совершенно иной. Наше выражение всегда будет ложным, исключая значение ival, равное нулю!
Более высокий приоритет оператора логического отрицания приводит к тому, что он выполняется первым, действуя на ival. Если ival имеет ненулевое значение, результат-ложный, в противном случае - истинный. Полученное значение становится левой частью операции получения остатка. False становится «О» при использовании в арифметических операциях, a true принимает значение «1». В результате порядка выполнения операций выражение превращается в 0%2 для любых значений ival за исключением нуля.
Хотя мы не хотели получить данный результат, он не является ошибкой, по крайней мере, языковой ошибкой. Это лишь неправильное представление нашей задуманной программной логики. Компилятор об этом, конечно, не догадывается. Порядок выполнения - это одна из причин, затрудняющих программирование на С++. Для правильного выполнения выражения мы должны изменить порядок выполнения с помощью скобок:
! (ival % 2) // ok
Чтобы избежать этих проблем, необходимо поближе познакомиться с порядком следования операторов в С++. Я вам не помощник, в том смысле, что раздел не содержит ни полного перечня операторов, ни полного представления порядка следования операций - того, что я показал, должно хватить только для начала.