liveBook · Manning

Reference

As explained in Modern C, Third Edition

A pointer type is a C type whose values designate objects or functions in storage.

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

How Modern C, Third Edition covers it

How deep it goes
Develops declarations, validity, arithmetic, array-parameter rewriting, and type constraints while leaving pointer representation platform-dependent.
Examples
Uses a swap function, array-summing loops, one-past-array access, and multidimensional matrix parameters.
What it assumes
Assumes familiarity with declarations, arrays, and function calls while introducing pointer syntax first as an opaque type.
What you can do after
Apply pointer-based interfaces to modify objects and traverse arrays; diagnose null, out-of-bounds, and type-mismatched access.
How it connects
Connects pointers to arrays, function calls, the C memory model, and type conversions.

Also explained in

Compare how 17 books explain reference →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Modern C, Third Edition. The section links point to the parts of the book it draws on.