non-lvalue in assignment

Discussion in 'Programmer's Corner' started by Alex Xander, Jun 23, 2013.

  1. Alex Xander

    Thread Starter New Member

    Jun 23, 2013
    1
    0
    Code:
    Code ( (Unknown Language)):
    1.  
    2. #include <stdio.h>
    3. #include <stdlib.h>
    4. #include <math.h>
    5. typedef struct { char name[30];
    6.                  char lastname[30];
    7.                  int  points;
    8.                  }PLAYER;
    9. PLAYER input();
    10. PLAYER input()
    11. {
    12. PLAYER A;
    13. printf("Name?\n");
    14. scanf("%s",A.name);
    15. printf("Last Name?\n");
    16. scanf("%s",A.lastname);
    17. printf("Points?\n");
    18. scanf("%d",&A.points);
    19. return(A);
    20. }
    21. int main()
    22. {
    23. int i,n,*niz;
    24. niz = (int*)malloc(n*sizeof(int));
    25. do{
    26. printf("Number of Players?\n");
    27. scanf("%d",&n);
    28. }while(n<1);
    29.  
    30. for(i=0;i<n;i++)
    31. (niz+i)=input();
    32. system("pause");
    33. }
    34.  
    Line 30: non-lvalue in assignment
    I just need an explanation, why did the error occurred, how do I fix it, and what should I do to prevent that in future. Thanks
     
    Last edited by a moderator: Jun 24, 2013
  2. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,386
    1,605
    Exactly what was your intent when you wrote

    (niz+i)=input();

    Was it that :

    niz = input() - 1;

    An "lvalue" is an object or variable that can be assigned the value of the right side. (niz+1) is an expression.
     
  3. Papabravo

    Expert

    Feb 24, 2006
    10,140
    1,789
    niz is a pointer to an integer. bniz + i is also a pointer to an integer that is time sizeof(int) away from niz. What you want to do is "de-reference" the pointer with the '*' (star) operator.

    Try:
    *(niz+i) = input() ;
    The way to read such an expression is "the integer pointed at by (niz+i)"
    In compiler terms the star operator makes an l-value out of an address expression.
     
  4. WBahn

    Moderator

    Mar 31, 2012
    17,737
    4,789
    It would help if you gave some indication of which line is line 30, instead of making us count and hoping that you included exactly the code that the compiler was basing its line numbers on. Also, format your code so that it is easy for others to read. If you want a stranger to look over your code, then it is to your benefit to make your code easy to look over. Doesn't that seem reasonable?

    Because you made a mistake

    By correcting the mistake.

    Don't make that mistake again.

    To expect a more meaningful answer, it is generally helpful to give us an indication of what you were trying to get the code to do. As it is, we see what you told the code to do; obviously the two aren't the same, but you are only letting us see one side. So the best we can do is guess -- and why do you want to make the strangers you are asking for help have to guess at what you were trying to do?

    Based on the error message, I'm guessing (notice -- guessing!) that the line that is being complained about is:

    (niz+i)=input();

    What would be wrong with the following:

    42 = 3 + 17;

    The expression on the left side of the assignment operator can't be just a number because what the assignment operator does is it evaluates the expression on the right side of the operator and gets a value. It then stores that value at a memory location indicated by the expression on the left side of the operator. So what does it mean to store the value 20 in the value 42? Nothing! It's is a meaningless statement -- and so when you tell the compiler to do something like this, it complains and tells you that the expression on the left side of the assignment operator is not an 'lvalue', meaning something that can be written to.

    But what if you wanted to write the result of 3+17 not to the value 42, but rather to memory location whose address is 42? Well, that's a perfectly reasonable thing to do. We do this using the "indirection" or "dereference" operator, which is the '*' character. So

    *42 = 3 + 17;

    is perfectly valid (though it may throw a runtime exception if you don't actually have permission to write data to that location).

    What this says is, "Make the value stored at the address 42 equal to the value obtained by evaluating the expression 3+17."

    Which brings us to your code:

    (niz+i)=input();

    'niz' is a pointer to an integer. This means that 'niz' is a variable, just like any other variable, and that it stores a value of a particular type, namely a value this is normally used as a memory address. But that is all it is -- a value stored in a variable.

    The exoression (niz+i) is just an expression that evaluates to a value. In this case, it evaluates to a number that happens to be the address of the ith integer after the address stored in the variable 'niz'. But that's all it is -- a value, just like 42.

    To use it on the left side of an expression, you need to dereference it. So

    *(niz+1) = ...

    can be read as, "Make the value stored at the address obtained by evaluating the expression (niz+1) equal to ...."

    See how that works?
     
Loading...