I always thought that *&p = p = &*p in C. I tried this code:
#include <stdio.h>
#include <stdlib.h>
char a[] = "programming";
char *ap = &a[4];
int main(void)
{
printf("%x %x %x\n", ap, &*(ap), *&(ap)); /* line 13 */
printf("%x %x %x\n\n", ap+1, &*(ap+1), *&(ap+1)); /* line 14 */
}
The first printf line (line 13) gives me the addresses:
40b0a8 40b0a8 40b0a8
which are the same as expected. But when I added the second printf line, Borland complains:
“first.c”: E2027 Must take address of a memory location in function main at line 14
I was expecting to get:
40b0a9 40b0a9 40b0a9.
It seems that the expression *&(ap+1) on line 14 is the culprit here. I thought all three pointer expressions on line 14 are equivalent. Why am I thinking wrong?
A second related question: The line
char *ap = a;
points to the first element of array a. I used
char *ap = &a[4];
to point to the 5th element of array a.
Is the expression
char *ap = a;
same as the expression
char *ap = &a[0];
Is the last expression only more verbose than the previous one?
Thanks a lot…
When you use the C reference operator, it has to point to a valid lvalue, not an arbitrary expression. Thus,
&(ap+1)isn’t valid because the valueap+1is simply an expression, not a location. You can’t sayap+1 = foo();And yes, a is the same as &a[0] here. Note that *(a+b) is 100% equivalent to a[b] (see the top answer to Strangest language feature for an unusual example of this equivalence). When getting a pointer to a member of an array, you can use &array[i] or array + i. Example:
In this case, whether to use
array+ior&array[i]is a matter of style.&array[i]is arguably a better choice, as it is clearer that an array item is being gotten. Moreover, &vec[i] works with C++’s vectors, whereas vec+i does not.