dereferencing (*)
If a pointer is a slip of paper with a house number on it, dereferencing is the act of actually walking to that house and looking inside. The dereference operator is a single asterisk *: put it in front of a pointer and you get the value living at the address the pointer holds, instead of the address itself.
So with int *p = &x, the name p means 'the address', and *p means 'the int over there'. *p can be read (int y = *p; copies x's value out) and written (*p = 9; stores 9 into x). The type of the pointer decides how dereferencing behaves: *p on a double * reads 8 bytes as a double, while *p on a char * reads 1 byte. For pointers to structs there is a shorthand, p->field, which means the same as (*p).field. A subtle but important detail: in int *p the asterisk is part of the declaration (it says 'p is a pointer'), while in *p = 9 the asterisk is the dereference operator doing work — same symbol, two roles.
Dereferencing is where pointers earn their keep and where they bite. *p is only valid when p actually points at a live object you are allowed to touch. Dereferencing a null pointer, a dangling pointer, or an uninitialised wild pointer is undefined behaviour — often a segmentation fault, but sometimes a silent corruption that surfaces far away.
int x = 3; int *p = &x; printf("%d\n", *p); prints 3, then *p += 10; makes x become 13. p never changed — it still points at x — but *p reached in and modified x.
*p reads and writes the pointee; p itself stays put.
Never dereference a pointer you have not verified points somewhere valid. Always check the result of an allocation, and after free() the pointer is dangling — *p is undefined even though the bytes may look unchanged. A crash is the lucky outcome; silent corruption is the unlucky one.