Changing an object through a pointer
A declaration such as `double* p0;` makes `p0` a pointer to `double`, not a `double` object. In `void double_swap(double* p0, double* p1);`, the caller supplies pointers to two objects. The function can change those objects without changing the caller’s pointers. C passes the pointer values as arguments; it does not have pass by reference. section 11.0 section 2.4.2
A pointer is a derived type whose value refers to an object or function. Its `*` declaration syntax names the referenced type. Keep the pointer distinct from what it points to: a pointer can be reassigned without changing an object, while access through a pointer can change the object. Pointer representations depend on the platform; portable code uses the operations C defines rather than interpreting their bits. section 6.0 section 6.2 section 11.5
TAKEAWAY: Control the pointer’s state before using it.
- A pointer may be valid, null, or invalid. Initialize a pointer that has no object to `nullptr`; a null pointer tests false. A truth test cannot establish that a non-null pointer is valid. section 6.2 section 11.1.4
- Dereference only when the pointer designates an object of the appropriate type. An uninitialized pointer has an indeterminate state; using it is unsafe. section 6.2 section 11.1.4
Pointers and arrays are related, not identical. For an array argument, `a+i` points to element `i`, and `*(a+i)` accesses it. A function cannot recover the array’s length from the pointer, so an interface must supply the length separately. Array parameters in function declarations are rewritten as pointers; for multidimensional parameters, only the innermost dimension is rewritten. A pointer to an array is not a pointer to a pointer. section 11.1.2 section 11.3.2
double A[2] = { 0.0, 1.0, };
double* p = &A[0];
printf("element %g\n", *p); // Referencing object
++p; // Valid pointer
printf("element %g\n", *p); // Referencing object
++p; // Valid pointer, no object
printf("element %g\n", *p); // Referencing non-object
// Program failure
Follow `p` across this two-element array. After the second increment, it is a valid one-past pointer, but `*p` attempts to access an object that is not there. section 11.1.4
Pointer arithmetic must stay within the permitted range of the relevant array; the one-past position cannot be dereferenced. Type matters too: pointer types with different base types are distinct. An object pointer can convert to `void*` and back to its original type without changing its value, but `void*` removes type information. Avoid using that conversion to disguise a mismatch between the pointer type and the object accessed. section 11.1.4 section 12.0 section 12.4 section 12.5
















