Reputation: 6322
Most of what I've read about the address operator, &
, says it's used to get just that - an address. I recently heard it described differently, though, as producing a full-fledged pointer.
Given the following C code,
int i1 = 5;
int *p1;
p = &i1;
my understanding is that p1
references the int 5
by storing the address where i1
's data is stored and remembering that the data in that location is to be interpreted as an int
(which dictates how many bytes to read and how to interpret the read data).
Does the address operator yield both the address and the "type-awareness", or is the type-awareness just implicit since p1
was declared to be an int
pointer?
One of the things that got me wondering about this was seeing code like:
void myFunc(int *ptr);
int i = 5;
myFunc(&i);
Upvotes: 3
Views: 6428
Reputation: 141887
The &
operator simply returns a pointer to its operand. If its operand was an int
the resulting type will be int*
. If its operand was an int*
the resulting type will be int**
. For example, this program:
#include <stdio.h>
struct test {
int a;
int b;
int d;
};
int main ( ) {
struct test foo = { 0, 0, 0 } ;
printf( "%lu\n", (unsigned long)(&foo + 2) - (unsigned long)&foo );
}
Outputs 24 on my machine because the sizeof(struct test)
is 12, and the type of &foo
is known to be struct test *
, so &foo + 2
calculates an offset of two struct test
s.
Upvotes: 6
Reputation: 224822
The variable i1
has type int
, so the expression &i1
takes the address of an int
, yielding an expression of type int *
. This expression is then assigned to p1
, which is also of type int *
.
So now p1
points to the memory location of i1
, so the expression *p1
will be 5
.
Upvotes: 0
Reputation: 34205
While you're right that the type of &i1
is int*
, I think you're assigning too much weight to that idea. I wouldn't describe anything in C as "type-awareness" and there's definitely no "remembering that the data in that location is to be interpreted as type int
". C types exist only at the source level and not after compilation.
This may be clearer in an example with union:
union something {
int a;
char b;
};
now if you have a variable x
of type something
, you can have &x.a
of type int*
and &x.b
of type char*
, but they're pointing at the same address.
Upvotes: 3