2011-12-20 1 views
1

Я получаю ошибку "lvalue required as left operand of assignment".lvalue требуется как левый операнд назначения (программа C)

Он назначает на линии:

if(ch=='.' || ch=='"' || ch=='(' || ch=')' || ch=='!' || ch==',' || ch=='?' || ch==';') { etc } 

Я просто хочу, чтобы проверить, если персонаж я смотрю на это равно ни одному из этих символов. Любая идея об исправлении?

Спасибо,

+0

Ничего себе, какая глупая ошибка! Большое вам спасибо. – Ellea

ответ

10

ch=')' должен быть ch==')'. Причина вы получаете эту конкретную ошибку, потому что в то время как == имеет более высокий приоритет, чем ||, = имеет более низкий приоритет, так что:

ch == '(' || ch = ')' 

обрабатывается как

((ch == '(') || ch) = ')' 

который пытается присвоить ')' к результат (ch == '(') || ch), который является rvalue и не может быть назначен. Это общая ошибка, и этот метод используется, чтобы избежать его:

if ('.' == ch || '"' == ch || ...) 

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

if ('.' = ch) 

Вы получите ошибку компилятора.

+2

Да, я помню технику ... Как-то я не мог заставить себя использовать ее, потому что она читается так неестественно. Я так рад, что современные IDE обнаруживают отсутствие '=' знаков в условиях! – dasblinkenlight

+0

@dasblinkenlight да, я не использую его ни по той же причине, я просто рекомендую его людям как вариант –

+0

Я не понимаю, почему 'ch = ')'' должен вызывать ошибку OP. – Pubby

0

Ваша непосредственная проблема заключается в том, что вы используете = (назначение), а в == (равенство):

if(ch=='.' || ch=='"' || ch=='(' || ch=')' || ... 
            ___^____ 
            see here 

То, что происходит это делать с относительным приоритетом различных битов. Хотя == будет связываться на более высоком уровне, чем ||, a == b || c == d оценивается как (a == b) || (c == d).

Однако = не связывается на более высоком уровне, поэтому a == b || c = d оценивает как ((a == b) || c) = d). С вашего кода, который заканчивается с частью выражения:

('(' || ch) = ')' 

Другими словами, вы пытаетесь присвоить ')' с невыполнением Lvalue '(' || ch.

Вы на самом деле повезло, там не parenthesising каждый член (которые многие люди), так, что бы сделать его синтаксически правильно, но не делать то, что вы ожидаете, во время выполнения:

if ((ch == '.') || (ch == '"') || (ch == '(') || (ch = ')') || ... 
             _________^^^^^^^^^^_________ 
             will assign rather than test 

Обычный подход, чтобы избежать то есть поставить постоянный первый, но, как вы, я считаю, что это просто некрасиво :

if (('.' == ch) || ('"' == ch) || ('(' == ch) || (')' = ch) || ... 
                ^^^^^^^^ 
               /urk! \ 

Когда я делаю такого рода вещи, я склонен полагаться на стандартной библиотеки, так что мой код выглядит лучше и имеет гораздо меньше шансов быть неправильно:

if (strchr (".\"()!,?;", ch) != NULL) { 
    // It's valid. 
} 

или даже лучше:

#define VALID_PUNCTUATION ".\"()!,?;" 
if (strchr (VALID_PUNCTUATION, ch) != NULL) { 
    // It's valid. 
} 

или даже лучше, чем, поставить весь сегмент в функции и просто использовать что-то вроде:

if (isValidPunctuation (ch)) { 
    // It's valid. 
} 

(вы все равно должны будете убедиться, что код в функции является правильным, но ваша mainline код будет намного чище).

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