2013-08-04 6 views
-1

Я знаю о значении C-языка Lvalue! Я знаю от 2 до 3 случаев, когда мы получаем эту ошибку! Lvalue означает: требуется левое боковое значение!Lvalue требуется ошибка путаницы?

1) мы получаем, когда мы назначаем константу/литерал константе вместо переменной!

void main() 
{ 
    int a; 

    a = 2; 

    8 = 7;//Left side value (variable) required! 
} 

2) с операторами сокращения до и после приращения!

void main() 
{ 
    int a = 2; 

    ++a; 
    a++; //variable value is updating! 

    ++2; 
    2++; //variable value has to be updatable! not a constant/literal value! 

    /* 
     Both pre & post unary operators workflow is Right --> Left. 
     Compiler treats this is also an assignment, So assignment always 
     happens to left side only! 
     That's why in these cases also compiler shows: Lvalue required error! 
    */ 
} 

3) сложное заявление!

void main() 
{ 
    int a = 2, b; 

    b = ++a++; 

    /* 
     ++a++ 
     evaluation is... 
     1st precedence is pre operator! 
     So, 

     ++a --> 2 is substituted! 

     ++a++; --> 2++ : variable value has to be updatable! not 
         a constant value! Lvalue required error! 
    */   
} 

Но как здесь, в этих случаях, мы получаем Lvalue, требуемую ошибку? Ищет более подробную информацию!

main() 
{ 
    int a=1, b; 

    //How come here we get Lvalue required error? 
    b = a+++++a; 
    b = a-----a; 

    //If i give spaces like below, compiler not getting confusion, no error! 
    b = a++ + ++a; 
    b = a–- – --a; 

    //here without spaces also i’m not getting any error! 
    b = a–-+–-a; 
} 

Пожалуйста, кто-то дает подробную оценку операторов на этих утверждениях!

//without spaces! 
b = a+++++a; 
b = a-----a; 

b = a--+--a; 

//with spaces! 
b = a++ + ++a; 
b = a-- - --a; 
+0

И 'int main()'. Ни один достойный программист не использует 'void' в качестве возвращаемого типа' main() '. –

+0

Вы можете посмотреть сгенерированный код или промежуточное представление компилятора. С помощью GCC попробуйте выполнить компиляцию с помощью 'gcc -Wall -S -O -fverbose-asm' или' gcc -fdump-tree-all' или использовать [MELT-зонд] (http: //gcc-melt.org#probe_id) –

ответ

8

Потому что лексер - это автомат, а не человек.

Он знает только, что ++ является токеном. Когда он встречает +, он ищет следующий символ - если это +, тогда он рассматривает эти два как токен ++.

Так, a+++++a является не разобранный, как a++ + ++a (как вы, кажется, ожидать), но, как a++ ++ + a, что, конечно, ошибка - вы можете не увеличивать a++ себя.

То же самое применимо к -. Конечно, если вы включаете пробелы, то вы в основном говорите лексеру, что «вот маркерная граница», поэтому он действительно сделает то, что вы ожидаете от него.

Относительно того, почему вы не получаете ошибку при написании a–-+–-a: опять же, у вас есть -- маркер, затем + маркер, то другой -- - этот случай однозначна,, потому что после встречи с +, так как лексический знает, что в нем нет значка +-, он правильно относится к + как плюсу, затем он правильно и правильно использует --.


уроки:

  1. Часто повторяемая фраза "в C, пробельные не имеет значения" является ложным.

  2. Вы помещаете пробел между вашими жетонами. Довольно пожалуйста.

  3. И не смей писать выражения и высказывания, подобные этому в любом случае, потому что они вызывают неопределенное поведение.

+3

+1 Мне нужна книга всех ваших ответов на SO: D – P0W

+0

@ P0W Спасибо! Но, честно говоря, я думаю, что это совершенно очевидно, если вы немного знаете о том, как работает ваш компилятор (и почему бы и нет?) –

+0

да, даже «очевидные» вещи отвечают красиво. – P0W

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