I'm just wondering why people/books/experts say "the function returns a
pointer to.." or "we have to send scanf a pointer to.." instead of "the
function returns the address of.." or "we have to send scanf the
address of.."
Isn't the lvalue called a POINTER TO and the (r)value called the
ADDRESS OF?
No.
Suppose I write:
sizeof(int *)
What is the parenthesized "int *" here? Is it an lvalue? Is it an
rvalue?
The last two questions can be safely answered with "no" and "no"
respectively -- it is neither an lvalue nor an rvalue. The answer
to the first question is that it is a type-name. The type named is
"pointer to int".
What a pointer *is*, then, is part of a type-name. Formally,
a variable (object) of type "int *" holds a value of type "int *":
int *p;
...
p = <some expression>
The <expression> here must have type "pointer to int", or be directly
convert-able to that type, e.g., from malloc():
p = malloc(N * sizeof *p); /* get room for N items */
(here we have a value of type "void *" on the right hand side of
the "=" assignment operator, and "void *" can be converted to "int *").
Simple textbook examples generally start with something like:
int i;
int *p;
...
p = &i;
Here the unary "&" (or "address-of") operator "takes the address"
of the ordinary variable "i", producing a value of type "pointer
to int", pointing to i.
If we then write either:
ret = scanf("%d", p);
or: ret = scanf("%d", &i);
the same thing happens in both cases: scanf() gets, as its second
value, the address of the variable "i": a value of type "pointer
to int", pointing to "i". (The first value is the address of the
first element of the array holding the sequence {'%', 'd', '\0'},
which is a value of type "char *".)
All values in C always have types. Most of the time, when we speak
or write informally, we believe that both the speaker/writer and
listener/reader already understand this and agree as to all the
types, so we just talk about the "value part" of the <type,value>
pair. That is, we do not go around saying:
start i at int 0, then add int 1 each trip through the loop
We omit the "int" part each time. If we do the same with pointers,
we might start with something like:
scanf("%d", &i)
call scanf, passing as the first value a value of type "char *"
pointing to the percent sign in the three-character array holding
the %d format directive, and passing as the second value a value
of type "int *" pointing to the local variable named "i"
(the full, formal version) and end up with:
call scanf with a pointer to "i"
or even more colloquially:
give scanf the address of "i"
but these all *mean* the same thing.
Why do people refer to the (r)values moving around in a program as
pointers? (Am I missing something, or just reading too much into a
non-issue?)
I think the last.
[I've noticed that experts almost never say "address of", but often
time beginners do... there must be something to it]
I prefer to reserve the term "address of" for the unary-& operator
myself, but this is something of a matter of taste.