An integer variable containing an address in memory, ie "pointing" to it. Some ProgrammingLanguages even permit you to do Pointer arithmetics. However, that is a very error prone task (in fact, bug source #1). Therefor, Pointer arithmetic is nowadays frowned upon unless you are doing low level systems programming.

Pointers also break type safety. Many ProgrammingLanguages attempt to alleviate this by requiring you to use a different type of Pointer for each kind of DataType you want to point to.

Nowadays, if you aren't writing a kernel or hardware driver, you should be using a ProgrammingLanguage that has GarbageCollection and frees you from the arduous task of keeping track of your memory. A common requirement of such languages is that programs don't perform arbitary bitswise opertaions on pointers, so that the garbage collector can find and follow pointers. This requirement is common implemented via the type system.

Ignoring complete hacks, pointers are always of a fixed size and the size (or width) of a pointer controls how much memory (RAM) can be addressed. There are 16bit, 32bit and 64bit address spaces in wide use, plus smaller address spaces for use in small embedded devices. When using pointers the address space appears as a huge array of size 2^n bytes. Not all of the address space is addressable (for example in C/C++ NULL maps to the pointer 0x00000000 (on most hardware anyway) which is not addressable. Other areas of the address space may me mapped to DMA devices and other things, such as the system clock (see mmap(2)).