The member access operators (dot . and arrow ->) are used to access a member of a struct.
Member of object
Evaluates into the lvalue denoting the object that is a member of the accessed object.
struct MyStruct
{
int x;
int y;
};
struct MyStruct myObject;
myObject.x = 42;
myObject.y = 123;
printf(".x = %i, .y = %i\n", myObject.x, myObject.y); /* Outputs ".x = 42, .y = 123". */
Member of pointed-to object
Syntactic sugar for dereferencing followed by member access. Effectively, an expression of the form x->y is shorthand for (*x).y — but the arrow operator is much clearer, especially if the structure pointers are nested.
struct MyStruct
{
int x;
int y;
};
struct MyStruct myObject;
struct MyStruct *p = &myObject;
p->x = 42;
p->y = 123;
printf(".x = %i, .y = %i\n", p->x, p->y); /* Outputs ".x = 42, .y = 123". */
printf(".x = %i, .y = %i\n", myObject.x, myObject.y); /* Also outputs ".x = 42, .y = 123". */
Address-of
The unary & operator is the address of operator. It evaluates the given expression, where the resulting object must be an lvalue. Then, it evaluates into an object whose type is a pointer to the resulting object's type, and contains the address of the resulting object.
int x = 3;
int *p = &x;
printf("%p = %p\n", (void *)&x, (void *)p); /* Outputs "A = A", for some implementation-defined A. */
Dereference
The unary * operator dereferences a pointer. It evaluates into the lvalue resulting from dereferencing the pointer that results from evaluating the given expression.
int x = 42;
int *p = &x;
printf("x = %d, *p = %d\n", x, *p); /* Outputs "x = 42, *p = 42". */
*p = 123;
printf("x = %d, *p = %d\n", x, *p); /* Outputs "x = 123, *p = 123". */
Indexing
Indexing is syntactic sugar for pointer addition followed by dereferencing. Effectively, an expression of the form a[i] is equivalent to *(a + i) — but the explicit subscript notation is preferred.
int arr[] = { 1, 2, 3, 4, 5 };
printf("arr[2] = %i\n", arr[2]); /* Outputs "arr[2] = 3". */
Interchangeability of indexing
Adding a pointer to an integer is a commutative operation (i.e. the order of the operands does not change the result) so pointer + integer == integer + pointer.
A consequence of this is that arr[3] and 3[arr] are equivalent.
printf("3[arr] = %i\n", 3[arr]); /* Outputs "3[arr] = 4". */
Usage of an expression 3[arr] instead of arr[3] is generally not recommended, as it affects code readability. It tends to be a popular in obfuscated programming contests.