2011-02-04 2 views
1

Salute ..Оператор Приоритет ..() и ++

У меня есть необычная проблема. Here in this table в библиотеке MSDN мы можем видеть, что приоритет () выше ++ (Pre-increment). , но когда я запускаю этот код, кажется, что приоритет ++ (prefex) выше:

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

    return 0; 
} 

и ответ:

х = 6

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

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

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

    return 0; 
} 

х = 4

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

+2

Проверьте [этот вопрос на вопрос] (http: // stackoverflow.com/q/4176328/238902) для получения дополнительной информации о точках последовательности – Default

+1

Используемая вами таблица предназначена для JScript. Используйте один для C++. http://msdn.microsoft.com/en-us/library/126fe14k%28v=vs.10.0%29.aspx – RedX

ответ

8

Как обычно, это неопределенное поведение. Нет sequence point на +, поэтому в какой точке не указано ++a. Это не проблема приоритета.

+0

@ C77431 - В этом порядке вы вставили из MSDN, нет оператора ++ (: 'operator ++' изменяет значение переменной, любые изменения переменных должны быть разделены точкой последовательности, чтобы все было четко определено, и здесь у вас нет точки последовательности. –

+0

спасибо, я получил точку (: – C77431

4

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

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


EDIT: - как я вижу, вы не понимаете проблемы здесь, я добавлю еще некоторую информацию:

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

Лучше?

+0

Это не просто неопределенный который будет оцениваться первым, поведение программы в целом полностью не определено при строгом чтении стандарта. – bdonlan

+0

@bdonlan - да, вы совершенно правы –

+0

Я думал, что первый пример был хорош .. Редактировать почти сделало его более сложным: P – Default

2

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

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

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

2

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

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

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

5

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

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

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

+0

В таблице говорится: «Вызов функций и группировка выражений», поэтому я думаю, что они означают оба использования круглых скобок. По общему признанию, это таблица JScript, поэтому ее релевантность вызывает сомнения. –

+0

Вы правы, я не обратил внимания на это в таблице. В этом случае таблица неверна :-). Скобки, используемые для группировки выражений, не являются оператором, и нет смысла назначать им приоритет (в JScript или где-либо еще). Вопрос о том, имеют ли скобки приоритет над операторами, не возникает, поскольку в синтаксисе относительно круглых скобок нет двусмысленности, тогда как этот вопрос возникает для всех операторов, включая оператор вызова функции(), и, следовательно, эти операторы должны быть назначенные приоритеты. (Кроме того, операторы «делают что-то», скобки - это просто синтаксис.) – joriki

+0

Почему мы обсуждаем приоритет оператора JScript, когда вопрос о C++? Почему бы не использовать для этого таблицу правильных приоритетов? http://msdn.microsoft.com/en-us/library/126fe14k%28v=vs.10.0%29.aspx – RedX

0

Это мое понимание того, что когда-либо использовать что-то вроде ++ в формуляре, для математики используется копия значения «a», поскольку «++» работает только после других операций, формула никогда не обновляется. но я могу ошибаться.

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

0

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

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

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