Ответ 1
Назначение имеет более низкий приоритет, чем тернарный оператор, поэтому строка оценивается как:
((a>b)?b=a:b)=b;
использование:
b=(a>b)?a:b;
У меня есть:
#include<stdio.h>
int main()
{
int a=5,b=6;
(a>b)?b=a:b=b; // Here is the error
return 0;
}
Но если я заменю:
(a>b)?b=a:b=b; // Error
with
(a>b)?(b=a):(b=b); // No-Error
Я понимаю, что lvalue
- это значение, для которого что-то можно назначить, и как оно отличается от rvalue
, но почему значение extra parenthesis
делает разницу.
Назначение имеет более низкий приоритет, чем тернарный оператор, поэтому строка оценивается как:
((a>b)?b=a:b)=b;
использование:
b=(a>b)?a:b;
Собственно, в C этот код
(a>b)?b=a:b=b;
анализируется многими компиляторами как
((a>b)?b=a:b)=b;
что является ошибкой, так как выражение ((a>b)?b=a:b)
оценивает значение r, которое вы пытаетесь назначить с помощью b
, что приводит к ошибке. Попытка присвоить rvalue является ошибкой. Если он не разбирается таким образом, то это просто синтаксическая ошибка. Но компилятору C НЕ разрешается анализировать его как:
((a>b)?b=a:(b=b)); //not allowed to parse by C language
Поскольку грамматика C не позволяет компилятору анализировать код, как указано выше.
Но то, что вы написали (исходный код) правильно, как С++.
Здесь грамматики C и С++ сильно различаются. И из-за этой разницы вы видите, что оба языка относятся к выражению по-разному. То есть the conditional expression in C++
отличается от the conditional expression in C
.
Wikipedia имеет очень хорошее и правильное объяснение для этого:
Связывание операторов в C и С++ (в соответствующем Стандарты) на факторизованном языке грамматики, а не приоритета Таблица. Это создает некоторые тонкие конфликты. Например, в C, синтаксис условного выражения является:
логическое-OR-выражение? выражение: условное выражение
а в С++ -
логическое-OR-выражение? выражение: Назначение выражение
Следовательно, выражение:
e = a < d? a ++: a = d
анализируется по-разному в двух языки. В C это выражение является синтаксическая ошибка, но многие компиляторы разбора это как:
e = ((a < d? a ++: a) = d)
что является семантической ошибкой, поскольку результат условного выражения (который может быть ++) не является значением lvalue. В С++ он анализируется как:
e = (a < d? a ++: (a = d))
который является допустимым выражением.
Это действительно:
((a>b)?b=a:b)=b;
Примечание: вам просто нужно
b = (a>b)?a:b;
Когда мы помещаем уравнение в скобки, оно рассматривается как выражение. И он возвращает некоторое значение, которое обеспечивает решение ошибки.