The & (address) operator yields a pointer to its operand. The operand must be an lvalue, a function designator, or a qualified name. It cannot be a bit field, nor can it have the storage class register.
If the operand is an lvalue or function, the resulting type is a pointer to the expression type. For example, if the expression has type int, the result is a pointer to an object having type int.
If the operand is a qualified name and the member is not static, the result is a pointer to a member of class and has the same type as the member. The result is not an lvalue.
p_to_y = &y;
The
address operator has been extended to handle vector types, provided that vector support is enabled.
The result of the address operator applied to a vector type can be
stored in a pointer to a compatible vector type. The address of a
vector type can be used to initialize a pointer to vector type if
both sides of the initialization have compatible types. A pointer
to void can also be initialized with the address
of a vector type.
The ampersand symbol & is used
in C++ as a reference declarator in addition to being the address
operator. The meanings are related but not identical. int target;
int &rTarg = target; // rTarg is a reference to an integer.
// The reference is initialized to refer to target.
void f(int*& p); // p is a reference to a pointer
If
you take the address of a reference, it returns the address of its
target. Using the previous declarations, &rTarg is
the same memory address as &target.You may take the address of a register variable.
You can use the & operator
with overloaded functions only in an initialization or assignment
where the left side uniquely determines which version of the overloaded
function is used. 
The
address of a label can be taken using the GNU C address operator &&.
The label can thus be used as a value.