home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / snip9707.zip / RLVALUE.TXT < prev    next >
Text File  |  1997-07-05  |  5KB  |  135 lines

  1. +++Date last modified: 05-Jul-1997
  2.  
  3.             A Brief Tutorial on Pointers, Lvalues, & Rvalues
  4.  
  5.       a public domain tutorial by Ruurd Pels (FidoNet 2:282/317.19)
  6.  
  7.  
  8.  
  9.  Q: Okay, I'm kinda new to C, and I was reading that this following example
  10.  Q: would not be good to do: main() {
  11.  Q:         int *iptr;
  12.  Q:         *iptr = 421;
  13.  Q:         printf("*iptr = %d\n",*iptr);
  14.  Q: }
  15.  Q: It was saying that you could get away with it, but in larger programs it
  16.  Q: can be a serious problem. It says that it is an uninitialized pointer.
  17.  
  18.  A: Contrary to what they (the book) told you, you CANNOT get away with 
  19.     uninitialized pointers, period.
  20.  
  21.  Q: How do you initialize pointers?
  22.  
  23.  A: Some insights:
  24.  
  25.  
  26. 1.  A variable, any variable, has, among others, two properties called the
  27.     rvalue and the lvalue. 'l' and 'r' stand for 'left' and 'right'.  What is
  28.     the meaning of these properties. Consider assignment:
  29.  
  30.         int l = 2;
  31.         int r = 3;
  32.  
  33.         l = r;        <----
  34.  
  35.     Conceptually speaking, what basically happens is that the compiler takes
  36.     the address of 'r' and retrieves the value stored at that address.  To
  37.     obtain the address, it uses the rvalue of 'r'. Now it is clear that
  38.     rvalues are used at the right hand side of the assignment operator to
  39.     obtain the address to use.
  40.  
  41.     Then, the value retrieved from 'r' is put in the lvalue of 'l', then,
  42.     'l'-s rvalue is used to obtain the address where to store that value.
  43.  
  44.     Definitions:
  45.  
  46.     rvalue    the attribute of a variable that holds the address where
  47.               that particular variable is stored.
  48.     lvalue    the attribute of a variable that holds the value of the
  49.               variable.
  50.  
  51.     Conclusions:
  52.  
  53.     -   If you never assign a value to a variable's lvalue, that lvalue is
  54.         undefined!
  55.     -   The effect of using undefined lvalues is undefined, possibly
  56.         harmful, and sometimes interesting ;-)
  57.     -   A variable is a tuple(address, value). See "Aside".
  58.     -   Assigning to rvalues is the job of the compiler.
  59.     -   Assigning to lvalues is the job of the programmer.
  60.  
  61.     Aside:
  62.  
  63.     In fact, a variable is tuple(storage, scope, type, address, value):
  64.  
  65.     storage     :   where is it stored, for example data, stack, heap...
  66.     scope       :   who can see us, for example global, local...
  67.     type        :   what is our type, for example int, int*...
  68.     address     :   where are we located
  69.     value       :   what is our value
  70.  
  71. 2.  A pointer is not a second class citizen. It has exactly the same proper-
  72.     ties as any other variable. The fun thing is that a pointers lvalue is
  73.     actually the rvalue of another variable, namely the variable it points
  74.     to.  That means that before we can use that lvalue, we first must assign
  75.     a correct value to it, because if we do not, that lvalue is undefined.
  76.     That is where the referencing operator '&'. comes into play. Consider:
  77.  
  78.         int  v = 3;
  79.         int* p;
  80.  
  81.         p = &v;         <----
  82.  
  83.     What the &-operator does is a modification of what happens at the left
  84.     side of the assignment. Basically it tells the compiler not to use 'v'-s
  85.     rvalue to obtain the address where the lvalue of 'v' is stored, but it
  86.     tells it to use the rvalue of 'v' as the right hand side of the
  87.     assignment.  It then proceeds as normal, assigning the value obtained to
  88.     the lvalue of p and storing that at the address contained in the rvalue
  89.     of p.
  90.  
  91.     What we have now is a p with an rvalue that is equal to the address where
  92.     p is stored, and an lvalue that is equal to the address where 'v' is
  93.     stored.  Bingo! We initialized a pointer.
  94.  
  95.     Conclusion:
  96.  
  97.     -   The meaning of the symbol '&' in the context of a variable is
  98.         "take-the-address-instead-of-the-value"
  99.  
  100. 3.  Now, all we need is a method to obtain the lvalue of 'v' through the
  101.     pointer p. That is where dereferencing operator '*' comes into play.
  102.     Consider:
  103.  
  104.         int   n;
  105.         int   v = 3;
  106.         int*  p = &v;
  107.  
  108.         n = *p;         <----
  109.  
  110.     Now what happens, is that the *-operator tells the compiler to use the
  111.     lvalue of p to use as an rvalue to obtain the proper lvalue. What happens
  112.     exactly is:
  113.  
  114.     -   Take the rvalue of p.
  115.     -   Obtain the lvalue of p.
  116.     -   Use the lvalue of p as an rvalue to obtain the lvalue of the
  117.         variable pointed to.
  118.  
  119.     We call this process "dereferencing", that is, the pointer refers to
  120.     another variable (possibly another pointer) and we follow that reference
  121.     to arrive at the place we want to be.
  122.  
  123.     Conclusion:
  124.  
  125.     -   The meaning of the symbol '*' in the context of pointers is
  126.         "use-my-value-as-address".
  127.  
  128. Well, the answer is there. To initialize a pointer, we must point it to
  129. another variable by means of the &-operator. To obtain the value of the
  130. variable pointed to, we use the *-operator. However, keep in mind that
  131. operators & and * can have a different meaning in other contexts (notably
  132. bitwise AND and multiplication).
  133.  
  134. Grtz, RFP ;-)
  135.