Ошибка: 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;

Когда мы помещаем уравнение в круглые скобки, оно рассматривается как выражение. И это возвращает некоторое значение, которое обеспечивает решение ошибки.

Другие вопросы по тегам