awesome-everything RU
↑ Back to the climb

Base CS from zero

Value vs. address

Crux An address says which cell; a value says what is stored there. A value can itself be an address — that is the idea behind a pointer or reference. ''''Read the value at address X'''' is the operation that connects the two.
◷ 20 min

Look at these two sentences:

  • “The value at address 4 is 100.”
  • “The value at address 4 is an address — specifically, address 100.”

Both are perfectly valid. Both describe real things that happen in programs. Yet one of them — the second — is the idea that confuses every beginner and that every senior engineer uses without a second thought.

A value is just bits in a cell. Nothing stops those bits from being interpreted as an address. When a value is an address, you have a pointer — a cell whose content tells you where to look next. This lesson draws the sharpest possible line between what a value is and what an address is, so the pointer idea lands cleanly.

Goal

After this lesson you can precisely distinguish an address from a value, describe how a value can itself be an address (the concept of a pointer), and explain what it means to “read the value at address X” — the operation called dereferencing.

1

Recap: the two things a memory cell has. Every cell in memory has exactly two properties. First, its address: the fixed position number of the cell in the row, starting from 0. Second, its value: the bits currently stored in the cell, which can change at any time.

These two properties are always separate. The address is how you find the cell. The value is what you find once you are there. A cell at address 12 will always be at address 12, but today it might hold 255 and tomorrow it might hold 0.

2

An address is a number. A value is also a number. Here is where the crucial subtlety lives. On a 32-bit machine, addresses are 32-bit numbers (0 to about 4 billion). Values stored in a cell are also numbers — sequences of bits that can be interpreted as a number.

Because both are just numbers, a value stored in a cell can happen to be in the range of valid addresses. Consider a cell at address 5 that holds the value 12. Nothing about the number 12 says “I am an address” or “I am just data.” The bits are the same. The interpretation depends on how your program decides to use that value.

If you use 12 as a number for arithmetic, it is data. If you use 12 as an address — if you say “now go look at the cell whose number is 12” — then 12 is being treated as an address. The bits in the cell did not change; only the use changed.

3

A pointer: a value that is an address. When a cell contains a value that is intentionally used as an address — when the program stores address X in a cell, meaning “cell A’s value is the address of some other cell B” — that cell A is called a pointer (or in higher-level languages, a reference).

In low-level terms:

  • Cell A at address 5 holds value 12.
  • The program treats that 12 as an address.
  • It then reads cell B at address 12 to get the actual data.

Cell A points to cell B. A is the pointer. B is the cell being pointed to.

The pointer idea does not introduce new hardware. Pointers are just a convention: store an address-shaped number in a cell and remember that you intend to use it as an address. The hardware has no notion of “pointer” — it just loads whatever bits are in a cell.

4

Dereferencing: “read the value at address X”. The operation “use a value as an address to find another value” is called dereferencing or following the pointer. In the example above: cell A holds 12 (the pointer). To dereference A, you go to address 12 and read whatever value is there. You “chased” the pointer one step.

In most programming languages there is explicit syntax for this. In C you write *p (where p holds an address) to mean “the value at the address stored in p.” In Python and JavaScript you never see the address directly because the language dereferences object references automatically — but the hardware is doing the same thing.

The two-step process:

  1. Read cell A → get value 12 (an address).
  2. Read cell at address 12 → get the real data.

Without the first step the real data is unreachable.

Why this works

Why store an address in a cell at all? Why not just put the data directly where you need it?

Two reasons. First, indirection allows sharing: multiple cells can all hold the same address, meaning multiple parts of a program can reference the same single piece of data without copying it. Second, indirection allows updates: if cell A holds the address of the data, and the data moves to a new location, you update only cell A’s value (to the new address) and every pointer via A automatically follows the new location. Without indirection, you would need to update every copy of the data.

These two benefits — sharing without copying, and one-place updates — are why pointers and references appear in virtually every program.

12
5
6
7
8
9
10
11
99
12
Cell at address 5 holds value 12 (a pointer). Cell at address 12 holds value 99 (the pointed-to data). To dereference: read address 5 → get 12 → read address 12 → get 99.
Worked example

Tracing a two-step pointer read.

Memory state:

  • Address 0: value 3 ← this cell holds the address of the data we want
  • Address 1: value 0
  • Address 2: value 0
  • Address 3: value 71 ← this is the actual data

A program executes: “read the value at the address stored in address 0.”

Step 1 — Read address 0. The CPU reads the cell at address 0 and gets back 3. This is the pointer value — it is an address.

Step 2 — Read address 3 (the address we just found). The CPU reads the cell at address 3 and gets back 71. This is the actual data, the value the program wanted.

The program now has 71. It took two memory reads: one to find the address, one to read the data at that address.

If we had instead stored 71 directly at address 0, only one read would be needed. The indirection costs one extra read. That extra step is the price of the flexibility that pointers provide.

What if the value at address 0 were changed to 2? Then the same two-step operation would return the value at address 2 (which is 0 in our table). The pointer was updated; the data it references changed.

Common mistake

The most common mistake with the value-versus-address distinction: confusing “the value 12” with “address 12.” If cell at address 5 holds the value 12, that does not mean address 12 exists (it might not, if memory is smaller than 13 cells). It also does not mean cell 5 is somehow special or different from a cell holding the value 7. The value 12 becomes an address only when the program explicitly uses it as one. Raw bits have no inherent meaning — the meaning comes from how the program uses them.

Practice 0 / 5

Cell at address 7 holds value 3. A program reads address 7 and then reads the address it just got. What address does it read in the second step?

Cell at address 2 holds value 2. Cell at address 3 holds value 99. The program reads address 2, then uses that as an address. What value does it get from the second read?

A pointer is a cell whose value is used as an address. Does a pointer cell have an address of its own? Type 1 for yes, 0 for no.

Dereferencing a pointer requires how many memory reads total to get the final data value: 1 or 2?

Memory has 10 cells (addresses 0–9). Cell at address 4 holds value 15. Can the program dereference that pointer? Type 1 for yes (safe), 0 for no (out of range).

Check yourself
Quiz

Cell at address 8 holds the value 20. Cell at address 20 holds the value 7. A program dereferences address 8. What value does it get?

Recap

An address names a cell — it is a fixed position number. A value is the data currently stored in a cell — it can change. Because both addresses and values are just numbers, a value can be a valid address. When a program intentionally stores an address in a cell and uses that cell’s content as an address for a further memory read, that cell is a pointer (or reference). Using a pointer to get the final data is called dereferencing: read the pointer cell to get an address, then read that address to get the actual data — two memory reads instead of one. Indirection through pointers allows multiple parts of a program to share data without copying and lets a single update to a pointer redirect all references at once.

Continue the climb ↑Stack and heap
shortcuts expand
search
K
prev piece
k
next piece
j
cycle tier
t
this menu
?
sources3
expand
  1. 01
  2. 02
  3. 03

Trademarks belong to their respective owners. Editorial reference only.