Pointers and Arrays
This domain tests the array–pointer relationship precisely: when an array name decays, which pointer arithmetic is defined, and how multidimensional arrays and parameters change type.
Decay and indexing
- In most expressions an array converts to a pointer to its first element. The exceptions are the operand of
sizeof, the operand of unary&, and a string literal used to initialize an array. a[i]is defined as*(a + i), soi[a]is equally valid and&a[i] == a + i.- Pointer arithmetic is scaled by the pointed-to type: for
int *p,p + 1advancessizeof(int)bytes. Pointers may be subtracted only within the same array object (one past the end is allowed as an address, not as a dereference); the result has typeptrdiff_t. int *pandint (*q)[5]are different:p + 1moves oneint,q + 1moves a whole five-element array.
Arrays as parameters
- A parameter written
int a[10]orint a[]is adjusted toint *a, sosizeof ainside the function is the pointer size. Pass the length as a separate argument. - For a two-dimensional array only the first dimension may be omitted:
void f(int m[][4])meansint (*m)[4].
Worked example
int a[5] = {10, 20, 30, 40, 50};
int *p = a;
int (*q)[5] = &a;
printf("%d %zu %zu\n", *(p + 2), sizeof a, sizeof *q);
p + 2 points at a[2], so the first value printed is 30. sizeof a is 5 * sizeof(int), typically 20. q points at the whole array, so *q is the array and sizeof *q is also 20. In bytes, p + 1 advances 4 while q + 1 advances 20.
Traps
- Assuming
sizeofstill reports the array size inside a function; after decay it reports the pointer size. - Forming a pointer more than one past the end of an object is undefined even if it is never dereferenced.
char *s = "literal"; s[0] = 'X';is undefined; string literals are not modifiable.- Confusing
*p++(dereference the current target, then advancep) with(*p)++(increment the pointed-to value). int *a, b;declares one pointer and oneint.