Ошибка: lvalue требуется в этом простом C-коде? (Троичный с заданием?)
Я имею:
#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
сделать разницу.
4 ответа
Присвоение имеет более низкий приоритет, чем троичный оператор, поэтому строка оценивается следующим образом:
((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)
оценивает значение, которое вы пытаетесь присвоить b
что приводит к ошибке. Попытка присвоить значение является ошибкой. Если он не анализируется таким образом, то это простосинтаксическая ошибка. Но компилятору C НЕ разрешается анализировать его как:
((a>b)?b=a:(b=b)); //not allowed to parse by C language
Потому что грамматика C не позволяет компилятору анализировать код, как указано выше.
Но то, что вы написали (оригинальный код), правильно, как C++.
Здесь грамматики C и C++ сильно различаются. И из-за этой разницы вы видите, что оба языка трактуют выражение по-разному. То есть,the conditional expression in C++
отличается отthe conditional expression in C
,
В Википедии есть очень хорошее и правильное объяснение этому:
Связывание операторов в C и C++ определяется (в соответствующих стандартах) факторизованной грамматикой языка, а не таблицей приоритетов. Это создает некоторые тонкие конфликты. Например, в C синтаксис для условного выражения:
логическое ИЛИ-выражение? выражение: условное выражение
в то время как в C++ это:
логическое ИЛИ-выражение?выражение: присваивание-выражение
Отсюда и выражение:
е = а <д? а ++: а = д
анализируется по-разному на двух языках. В C это выражение является синтаксической ошибкой, но многие компиляторы анализируют его как:
e = ((a
что является семантической ошибкой, поскольку результат условного выражения (который может быть ++) не является lvalue. В C++ это анализируется как:
e = (a
которое является допустимым выражением.
Это правда:
((a>b)?b=a:b)=b;
Примечание: вы должны просто
b = (a>b)?a:b;
Когда мы помещаем уравнение в круглые скобки, оно рассматривается как выражение. И это возвращает некоторое значение, которое обеспечивает решение ошибки.