memory as an addressable array of bytes
Picture the main memory of a computer as one impossibly long street where every house is exactly the same size and holds one small thing, and every house has a number painted on the door. The 'house' here is a byte (8 bits), and the 'door number' is its address. From the program's point of view, memory is just this: a huge sequence of numbered boxes, each box holding one byte.
More precisely, memory is a flat array of bytes indexed from 0 upward. Byte 0, byte 1, byte 2, and so on, each independently readable and writable. There is nothing in the bytes themselves that says 'this is a number' or 'this is a letter' — a byte is just a bit pattern, eight 0s and 1s, and the meaning comes entirely from the code that reads it. A 4-byte integer like int x simply occupies four neighbouring boxes, say addresses 0x1000 through 0x1003.
This single idea — memory is a numbered array of bytes — is the foundation under pointers, the stack, the heap, and almost everything in this field. The hardware does add structure on top (caches, alignment, virtual addresses), but the C abstract machine lets you keep the simple street-of-boxes picture and reason correctly with it most of the time.
char buf[4] places four bytes side by side at, say, 0x1000, 0x1001, 0x1002, 0x1003; writing buf[2] = 65 stores the bit pattern 0x41 (decimal 65, the letter 'A') into the single box at 0x1002.
Four neighbouring bytes; index 2 is just the box at base + 2.
A byte is the smallest individually addressable unit in C; you cannot take the address of a single bit. The same eight bits can mean a small number, a character, a flag set, or part of a larger value — interpretation is the program's job, not the memory's.