Базовый CS с нуля
Адресуемые ячейки
Когда программа сохраняет число, машина должна куда-то его положить. Но «куда-то» — слишком расплывчато: машине нужна точная, однозначная позиция, чтобы потом найти это число снова. Как она добивается этой точности?
Ответ красиво прост: память устроена как длинный прямой ряд ячеек хранения, и у каждой ячейки есть номер — её адрес. Чтобы найти ячейку, называешь её номер. CPU запрашивает адрес 42 и получает обратно то, что лежит в ячейке 42. Никакого перебора, никаких догадок. Просто: «дай мне ячейку номер 42».
Эта единственная идея — пронумерованные ячейки — и есть фундамент того, как любой компьютер хранит данные и извлекает их.
После этого урока ты сможешь описать память как ряд пронумерованных ячеек, отличить адрес от значения и объяснить конкретными словами, что значит «CPU читает из адреса» или «CPU пишет по адресу».
Память как ряд ячеек. Компьютерная память (RAM — Random Access Memory, «память с произвольным доступом») физически построена из множества крошечных схем, каждая из которых хранит один бит. Для практического использования эти биты группируются, а группы выстраиваются в прямую последовательность — как сиденья в очень длинном ряду. Каждая группа — это ячейка памяти: слот для хранения значения.
Слово «ячейка» выбрано намеренно: представь ячейку таблицы в электронной таблице или почтовый ящик на почте. Каждая ячейка — контейнер. Её содержимое можно менять (перезаписывать), но сама ячейка навсегда закреплена на своей позиции в ряду. Ряд имеет чёткое начало (самая первая ячейка) и чёткую длину (общее количество ячеек в машине).
Адрес: постоянный номер ячейки. Каждая ячейка в ряду имеет уникальный номер, начиная с 0. Этот номер называется адресом ячейки. Адрес 0 — первая ячейка, адрес 1 — вторая, адрес 2 — третья, и так далее до последней ячейки.
Адрес не хранится внутри ячейки — он является позицией ячейки в ряду, как номер дома на улице. Номер дома не меняется, когда въезжают новые жильцы; точно так же адрес 7 всегда указывает на седьмую ячейку вне зависимости от того, какое значение та сейчас хранит.
Поскольку адреса начинаются с 0, память из N ячеек имеет адреса от 0 до N−1. Если в машине 1 000 ячеек, допустимые адреса — от 0 до 999. Запрос адреса 1 000 вышел бы за пределы — такой ячейки не существует.
Значение: то, что лежит в ячейке. Значение — содержимое ячейки, фактические данные, которые там хранятся. Значение можно изменить в любой момент: запишешь новое — старое исчезнет. Но адрес ячейки не меняется никогда.
Это разграничение принципиально важно:
- Адрес: какая ячейка. Фиксированный. Местоположение.
- Значение: что находится в этой ячейке. Изменяемое. Данные.
Ячейка по адресу 12 может хранить значение 0 прямо сейчас и значение 255 через пять миллисекунд — идентичность ячейки (адрес 12) постоянна, а её содержимое изменилось.
Почему это работает
Почему адреса начинаются с 0, а не с 1? На аппаратном уровне адрес — это двоичное число, и первый допустимый адрес — тот, у которого все биты равны 0, то есть число 0. Начало с 1 оставило бы адрес 0 неиспользованным, тратя одну позицию и усложняя арифметику. Начало с 0 делает адрес ячейки N равным ровно N, что упрощает любые вычисления со смещениями. Большинство языков программирования придерживаются той же договорённости для индексов массивов.
Чтение из памяти: CPU запрашивает по адресу. Чтобы получить сохранённое значение, CPU выполняет чтение памяти. Он помещает нужный адрес на шину адресов (набор проводников, соединяющих CPU с памятью), аппаратура памяти находит ячейку по этому адресу, и хранящееся там значение возвращается CPU по шине данных.
Ключевое наблюдение: CPU никогда не перебирает ячейки в поисках значения. Он называет адрес напрямую и немедленно получает ячейку. Именно это означает «произвольный доступ» в «RAM»: к любой ячейке можно обратиться прямо по адресу примерно за одинаковое время, без перебора предшествующих ячеек.
Запись в память: CPU отправляет адрес и значение. Запись в память — обратная операция: CPU отправляет одновременно адрес и новое значение. Аппаратура памяти находит ячейку по этому адресу и сохраняет там новое значение, перезаписывая всё, что было раньше. Ячейка теперь хранит новое значение до следующей записи.
Запись деструктивна в одном смысле: прежнее значение исчезает без следа. Если старое значение нужно сохранить, его следует прочитать перед записью нового.
Разбор операций чтения и записи.
Предположим, программа должна сложить два числа из памяти и сохранить результат.
Состояние до операций:
- Адрес 10 хранит значение
25 - Адрес 11 хранит значение
30 - Адрес 12 хранит значение
0(сюда запишется результат)
Шаг 1 — Чтение адреса 10. CPU отправляет адрес 10 в память. Память возвращает 25.
Теперь у CPU есть 25 в регистре (маленьком хранилище внутри самого CPU).
Шаг 2 — Чтение адреса 11. CPU отправляет адрес 11 в память. Память возвращает 30.
Теперь у CPU есть оба числа: 25 и 30.
Шаг 3 — Сложение. CPU складывает 25 + 30 = 55. Это происходит внутри CPU; память в арифметике не участвует.
Шаг 4 — Запись по адресу 12. CPU отправляет адрес 12 и значение 55 в память.
Память сохраняет 55 по адресу 12, перезаписывая старое значение 0.
Состояние после:
- Адрес 10:
25(не изменился) - Адрес 11:
30(не изменился) - Адрес 12:
55(обновлён)
Адреса 10 и 11 не изменились. Изменилась только та ячейка, в которую была выполнена запись.
Частая ошибка
Распространённая путаница: адрес и значение — это одно и то же, ведь оба являются числами. Это не так. Адрес — идентификатор местоположения, он указывает машине куда смотреть. Значение — данные, хранящиеся в этом местоположении. Адрес 42 — это не то же самое, что ячейка, в которой значение равно 42. Адрес 42 может хранить значение 7, а адрес 7 — значение 42: четыре комбинации, каждая своя.
Память содержит ячейки по адресам от 0 до 7. Сколько в ней ячеек? Введи число.
Ячейка по адресу 5 хранит значение 99. После записи значения 0 по адресу 5 — что хранит адрес 5?
Ячейка по адресу 3 хранит значение 42. Что вернёт чтение адреса 3?
Память имеет адреса от 0 до 255. Каков адрес самой первой ячейки?
По адресу 10 записали значение 7, затем по адресу 10 записали значение 3. Что вернёт чтение адреса 10?
Что требует операция чтения памяти в качестве входного параметра и что она возвращает?
Компьютерная память — длинный прямой ряд ячеек, каждая из которых идентифицируется уникальным числом — адресом. Адреса начинаются с 0 и увеличиваются на 1 для каждой следующей ячейки. Значение — данные, которые ячейка хранит в данный момент; оно может меняться, но адрес фиксирован. Чтение памяти принимает адрес и возвращает хранящееся там значение. Запись в память принимает адрес и новое значение и сохраняет его в ячейке, перезаписывая прежнее содержимое. CPU обращается к любой ячейке напрямую по адресу без перебора — именно это прямое обращение и называется «произвольным доступом».