Я пытался изучить ассоциативность операторов в C ++, и я наткнулся на сегмент кода:
int a = 10;
int C = a++ + ++a + ++a +a;
Я также изучил это ++a
является правым левым ассоциативным и a++
слева направо ассоциативно. Также +
слева направо ассоциативно. Но я не понимаю, как применить эти знания в этой проблеме.
Я запутался, что как этот оператор будет анализироваться моим компилятором?
Я также озадачен тем, что, так как размещение пробелов не имеет большого значения, почему удаление таких пробелов, как:
int C = a+++++a+++a+a; //error: lvalue required as increment operand
сгенерировать ошибку?
Пожалуйста, помогите мне понять эту концепцию.
Спасибо!
Прежде всего пространство имеет значение— Это помогает компилятору разрешить неоднозначность.
Всякий раз, когда есть выражение, компилятор анализирует его справа налево. Сначала он ищет все операторы постинкремента, а затем операторы предварительного инкремента, так как более поздний приоритет имеет более низкий приоритет, чем первый. Таким образом, любая модификация, выполняемая оператором предварительного увеличения, будет применена ко всему выражению, а затем изменения следующего увеличения будут применены в следующем выражении.
объяснение
В вашем случае есть всего два ++ a, поэтому значение a будет увеличено до 12 и, таким образом, присвоено a. так что все a в вашем выражении будут содержать значение 12, что дает вам значение c = 48.
В вашем случае, если вы используете значение a после выражения, это будет 13, так как в предыдущем выражении был только один a ++.
Например,
int a = 10;
int C = a++ + ++a + ++a +a; // Here a=12 and the post increment effect will be applied in the next expression
int B = a + a; // Here a=13 the effect of previous post increment.
По поводу ошибки
Если в выражении нет пробела, компилятор будет сбит с толку, когда будет анализировать выражение, и, следовательно, у dosent будет какое-либо значение для выполнения присваивания.
PS: lvalue — это значение, которое может быть целью назначения.
В C / C ++ операторы предварительного увеличения (уменьшения) и последующего увеличения (уменьшения) требуют выражения L-значения в качестве операнда. Предоставление R-значения или переменной с постоянным значением приводит к ошибке компиляции.
Оставляя в стороне тот факт, что это приведет к UB (так как нет последовательности точек между этими несколькими приращениями одной и той же переменной)
a+++++a+++a+a
анализируется (поскольку анализатор является жадным) как
((a++)++) + (a++) + a + a
а также (a++)++
незаконно, когда a
это встроенный тип как int
,