Data
Let’s begin with pointers.
int x = 42;
int* px = &x;
Raw pointers store addresses, and nothing else. Raw pointers even don’t guarantee the validity of addresses they hold. Raw pointers usually have types in modern programming languages, int* for example, which makes it easier to access data from it.
It is easy for programmers to access data from a pointer, thanks to abstractions:
int tmp = *px;
However, it is not that easy for a compiler to process a data access. To complete an access, the compiler needs to know not only where the data is stored, but also how the data is organized. This is our topic today: information structure.
At the lowest level that is useful to us, memory is a long sequence of bytes. Each byte has a numeric address, and an object occupies a consecutive range of addresses. A pointer stores the address of (usually) the first byte of an object. The pointer’s type tells the compiler how many bytes to read, how those bytes are aligned, and how to interpret them.
The same bytes can therefore have different meanings. The bit pattern 01000001 can be the integer 65, the character A, part of a floating-point value, or an instruction. An encoding gives a bit pattern a meaning; a type tells a programming language which encoding and operations to use.