Приоритет оператора .. () и ++ - PullRequest
1 голос
/ 04 февраля 2011

Приветствуйте ..

У меня необычная проблема. Здесь, в этой таблице в библиотеке MSDN, мы видим, что приоритет () выше, чем ++ (предварительное увеличение) . но когда я запускаю этот код, кажется, что приоритет ++ (предпочтения) выше:

int main()
{
    int a=3,b=2,x;
    x=++a + (a-b);
    cout<<"x= "<<x;

    return 0;
}

и ответ:

х = 6

Это происходит только с Предпочтительным ++ и работает как я ожидаю с постинкрементным .

Есть ли причина? С уважением ..

int main()
{
    int a=3,b=2,x;
    x=a++ + (a-b);
    cout<<"x= "<<x;

    return 0;
}

х = 4

(я использую Microsoft Visual C ++ 2010 express)

Ответы [ 8 ]

8 голосов
/ 04 февраля 2011

Как обычно, это неопределенное поведение + нет последовательности , поэтому не определено, в какой момент ++ обновляет a.Это не проблема приоритета.

5 голосов
/ 04 февраля 2011

Здесь есть два недоразумения.

Первое: в таблице () относится к вызовам функций, а не к скобкам, используемым для группировки. Круглые скобки, используемые для группировки, - это не оператор с определенным приоритетом, а средство для обеспечения интерпретации, отличной от той, которая задается приоритетом оператора. Таким образом, все, что сгруппировано в скобках, рассматривается как единое целое, независимо от того, каковы приоритеты операторов.

Второе: приоритет оператора относится к порядку приоритета, который операторы принимают при разборе, иначе неоднозначный синтаксис; это не относится к временному порядку побочных эффектов. Таким образом, префикс ++ всегда увеличивает значение перед вычислением выражения, posfix ++ всегда увеличивает значение после вычисления выражения, независимо от приоритетов синтаксических операторов.

4 голосов
/ 04 февраля 2011

Это x=a++ + (a-b); - неопределенное поведение, независимо от того, ++a или a++.

Причина в том, что вы звоните operator+ с двумя аргументами: a++ и (a-b), но не определено, какой из двух аргументов будет оцениваться первым.


РЕДАКТИРОВАТЬ: - как я вижу, вы не понимаете проблему здесь, я добавлю еще немного информации:

operator++ (постфикс или префикс, что угодно), изменяет значение переменной, так что это делает этот оператор более особенным, чем operator+, operator- и т. Д. 1021 * и a++ изменяют значение a, после этого вам нужно иметь точку последовательности, прежде чем снова использовать a. operator+ НЕ является точкой последовательности, так что вы как бы назвали operator+( ++a, (a-b) );. Стандарт НИЧЕГО не говорит о порядке оценки параметров, поэтому мы получаем неопределенное поведение .

Better

2 голосов
/ 04 февраля 2011

Я просто дам вам ссылку:

Очки последовательности

объяснил на StackOverflow.com Прасун Саурав

2 голосов
/ 04 февраля 2011

Это вызывает неопределенное поведение. Не существует последовательности между изменением a с помощью преинкремента или постинкремента и его использованием в выражении в скобках. Это на самом деле не имеет ничего общего с приоритетом оператора. Рассмотрим более простой пример:

int a = 1;
int b = (a=2) + a;

Каким должно быть значение b? Компилятору разрешается вычислять левую и правую части + в любом порядке, потому что в общем случае вы получите одинаковый ответ для обоих заказов, за исключением случаев, когда вы изменяете одну из переменных в выражении и ссылаетесь на нее снова без промежуточной точки последовательности. Как я уже сказал, это неопределенное поведение: один компилятор может дать 4, другой 3, третий может зажечь ваш компьютер.

2 голосов
/ 04 февраля 2011

Приоритет не определяет порядок оценки. Приоритет определяет, как операторы связываются с операндами; не порядок, в котором оцениваются операторы.

Таблицы приоритетов являются производными от грамматики, они не заменяют ее.

Кроме того, вы не должны предполагать, что таблица приоритетов JScript обязательно имеет какое-либо отношение к коду C ++.

0 голосов
/ 03 февраля 2016

У него нет проблем с приоритетом.

Если вы решите вопрос, то всякий раз, когда у нас есть оператор =, он будет решаться справа налево.Значит, выражение правой части будет решено, и ответ будет назначен переменной x.При решении выражения правой части у нас есть оператор +, который использует подход «слева направо» для решения.Поэтому сначала будет решено ++a, а затем будет решена скобка в соответствии с правилом.Так что ++a сгенерирует 4, а (a-b) даст 2, поэтому окончательное добавление даст результат 6.

0 голосов
/ 04 февраля 2011

Насколько я понимаю, когда вы используете что-то вроде a ++ в формуле, для математики используется копия значения "a", поскольку "++" работает только после других операций, формула никогда не обновляется , но я могу ошибаться по этому поводу.

так что если у вас есть x = ++ a + b, где вы a = 1 и b = 2 вы получите что-то вроде x = 1 + 2, а с x = a ++ + b вы получите x = 2 + 2 при подстановке значений.

...