Pointers allow programs to indirectly reference memory locations. They store the address of another variable. Pointers are used to pass variables by reference, dynamically allocate memory, and build complex data structures like linked lists. Pointer variables are declared with a type followed by an asterisk (e.g. int *ptr). The ampersand (&) operator returns the address of its operand. The indirection (*) operator accesses the value at the address a pointer refers to. Pointers can be passed as function parameters or returned as values. Dynamic memory allocation with functions like malloc, calloc, and realloc allow programs to request memory at runtime.