Ошибка: lvalue требуется в этом простом C-коде? (Троичный с заданием?) - PullRequest
11 голосов
/ 06 августа 2011

у меня есть:

#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 ]

20 голосов
/ 06 августа 2011

На самом деле, в C этот код

(a>b)?b=a:b=b; 

анализируется многими компиляторами как

((a>b)?b=a:b)=b;

, что является ошибкой, поскольку выражение ((a>b)?b=a:b) оценивается как rvalue , который вы пытаетесь присвоить с помощью b, что приводит к ошибке.Попытка присвоить rvalue является ошибкой.Если он не анализируется таким образом, то это просто ошибка синтаксис .Но компилятору 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 ++ это:

логическое ИЛИ-выражение?выражение: присваивание-выражение

Следовательно, выражение:

e = a

анализируется по-разному на двух языках.В C это выражение является синтаксической ошибкой, но многие компиляторы анализируют его как:

e = ((a

, что является семантической ошибкой,поскольку результат условного выражения (который может быть ++) не является lvalue.В C ++ он анализируется как:

e = (a

, которое является допустимым выражением.

9 голосов
/ 06 августа 2011

Назначение имеет более низкий приоритет, чем троичный оператор, поэтому строка оценивается следующим образом:

((a>b)?b=a:b)=b;

использование:

b=(a>b)?a:b;
2 голосов
/ 06 августа 2011

Это действительно:

((a>b)?b=a:b)=b; 

Примечание: вы должны просто

b = (a>b)?a:b;
0 голосов
/ 06 августа 2011

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

...