All variables of non-primitive types in Java are references. C has no concept of ‘reference’, but instead has pointers, which Java does not. They are similar, but you can do much more with pointers, with a correspondingly greater risk of mistakes.
A pointer is an address in memory of some ordinary data. A variable may be of pointer type, i.e. it holds the address of some data in memory.
/* We'll assume we're inside some block statement, as in a function. */ int i, j; /*i
andj
are integer variables. */ int *ip; /*ip
is a variable which can point to an integer variable. */ i = 10; j = 20; /* values assigned */ ip = &i; /*ip
points toi
. */ *ip = 5; /* Indirectly assign5
toi
. */ ip = &j; /*ip
points toj
. */ *ip += 7; /*j
now contains27
. */ i += *ip; /*i
now contains32
. */
The &
operator obtains the
address of a variable. The *
operator dereferences the pointer. While
ip
points to i
, then *ip
is synonymous with i
, and you
can use it in any expression where you could use
i
. A dereferenced pointer can
be used on the left-hand side of an assignment,
i.e. it is a modifiable
lvalue (‘el-value’), as in the two examples
above.
The characters &
and
*
also serve as binary
operators for bitwise AND and multiplication, but the
pointer operators are unary, so the syntax ensures that
there is no ambiguity. Furthermore, it is a common
convention to put spaces around binary operators, but not
between a unary operator and its operand, so it's usually
easy to see what these characters are being used for at a
glance.
C doesn't care whether you declare int
*ip;
or int*
ip;
. The type of ip
is
int
*
(or pointer-to-int
)
either way. However, some prefer the first form, because
it acts as a mnemonic that *ip
is an int
;
while some prefer the second, because it keeps the type
separate from the variable name. Note that the
*
does not propagate across
multiple variables in a single declaration, such as
int *ip,
i;
— i
is still just
an int
in that case.