2016-03-23 2 views
-1

Я пытался узнать ассоциативность операторов в C++, и я наткнулся на сегмент кода:C++: как этот оператор анализируется?

int a = 10; 
int C = a++ + ++a + ++a +a; 

Я также изучил, что ++a справа налево ассоциативно и a++ слева направо, ассоциативно. Также + слева направо ассоциативный. Но я не понимаю, как применять эти знания в этой проблеме.

Я смущен, что как этот оператор будет проанализирован моим компилятором?

Я также озадачены тем, что с тех пор положить пространства не имеет большого значения, почему удаление пространства, как:

int C = a+++++a+++a+a; //error: lvalue required as increment operand 

генерировать ошибку? Пожалуйста, помогите мне понять эту концепцию.

Спасибо!

+1

Первый приоритет оператора: http://en.cppreference.com/w/cpp/language/operator_precedence, вторые пространства имеют значение, особенно если они могут быть неоднозначными. Парсеры-компиляторы могут делать много вещей, но в целом: если человек не может его прочитать, - не может компилятор ;-) –

+1

Это не имеет ничего общего с разбором, но этот оператор не определен. Согласно стандарту, §1.9.15, стр.11 говорит: «За исключением тех случаев, когда отмечено, оценки операндов отдельных операторов и подвыражений отдельных выражений не подвержены». Далее: «Если побочный эффект скалярного объекта не влияет на какой-либо другой побочный эффект на один и тот же скалярный объект или вычисление значения с использованием значения одного и того же скалярного объекта, поведение не определено ». –

+0

Думаю, я должен сказать: если вы пытаетесь выяснить, какова будет ценность C, сдайтесь; вы не можете. –

ответ

2

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

Всякий раз, когда есть выражение, компилятор анализирует его справа налево. Он ищет все операторы приращения post, а затем pre increment операторы, поскольку более поздние имеют более низкий приоритет, чем первый. Таким образом, любая модификация, выполняемая оператором pre-increment, будет применяться ко всему выражению, а затем изменения последующего приращения будут применены в следующем выражении.

Объяснение

  • ++ первое приращение значения а, а затем возвращается со ссылкой на-значение а, поэтому, если используются, то он будет увеличиваться значением.

В вашем случае есть суммарные два ++ a, поэтому значение a будет увеличено до 12 и, таким образом, присвоено a. поэтому все a в вашем выражении будут удерживать значение 12, давая вам значение c = 48.

  • a ++ сначала возвращает значение rvalue, значение которого является a, то есть старым значением, а затем увеличивает его в неопределенное время до следующего полного выражения.

В вашем случае, если вы используете значение 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. 

Что касается ошибки

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

PS: lvalue - это значение, которое может быть целью присвоения. В C/C++ операторы pre-increment (decment) и post-increment (decment) требуют выражения L-value в качестве операнда. Предоставление значения R или константы, вызванной константой, приводит к ошибке компиляции.

+0

Спасибо большое @secretgenes Ваш ответ объясняет это мне так ясно :) – utkarsh867

1

Оставив в стороне тот факт, что это приведет к UB (а без точек последовательности между этими несколькими шагами одного и того же переменной)

a+++++a+++a+a 

проанализированным (как анализатор жаден), как

((a++)++) + (a++) + a + a 

и (a++)++ является незаконным, когда a является встроенным типом, как int.

Смежные вопросы