September 7, 2024

Старт в программировании на C: Данные в оперативной памяти

Программирование заключается в выполнении различных операций с данными для решения определённых задач. Данные могут принимать разные формы, такие как символы, строки или числа. Компьютеры работают только с двоичной информацией, поэтому всё, с чем они взаимодействуют, представлено в двоичном формате в оперативной памяти, которая организована как массив из элементов по 8 бит (1 байт).

В языке программирования Си разработана абстракция над этой структурой — переменные. Переменная хранит адрес, указывающий на расположение данных в оперативной памяти, а также их размер. Например, чтобы сохранить число, можно написать:

short a = 1;

В этом примере `short` — это тип переменной, который определяет доступные операции и размер данных (2 байта). Тип данных в основном нужен для предотвращения ошибок; важен лишь объём данных. Поэтому можно преобразовывать переменные разных типов, если их размеры совпадают, при этом данные в оперативной памяти останутся такими же, просто изменится их представление.

`a` — это имя переменной, с помощью которого мы обращаемся к её данным в памяти.

`= 1;` означает, что число 1 записано в оперативной памяти в двоичном формате.

чтобы в этом удостовериться напишем вот такой код:

#include <stdio.h>
int main(){
    short a = 1;
    printf("size=%lu\n", sizeof(a)); // size = 2
    printf("address = %p\n", &a);    // address = 0x7fff75c73d0e
    printf("data = %d\n", *&a);      // data = 1    
    return 0;
}

В этом коде:

1. Подключаем библиотеку `stdio.h`, которая позволяет выводить текст в консоль.

2. Создаем основную функцию `main()`, с которой начинается выполнение программы.

3. Объявляем переменную типа `short` (размером 2 байта) с именем `a` и присваиваем ей значение 1.

4. С помощью `printf` выводим в консоль размер переменной `a` в байтах.

5. Далее выводим адрес переменной `a` в оперативной памяти. Этот адрес отображается в шестнадцатеричном формате. Хотя он может показаться очень большим числом, на самом деле современные операционные системы используют виртуальную память, что может приводить к адресам, превышающим объем оперативной памяти. Однако на этом этапе это не столь важно.

6. далее выводим данные в оперативной памяти по адресу записанному в переменную.

6. Выходим из программы с кодом 0 (без ошибок).

Давайте представим ситуацию, которая произошла.

Предположим, что у нас есть оперативная память объемом 18 бит, и в ней уже записаны случайные данные после выполнения других программ. Запись выглядит следующим образом:

[0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0]

Когда процессор начнет выполнять команду

short a = 1;

он выделит часть оперативной памяти, равную 2 байтам (16 бит), и запишет туда число 1 в двоичном формате. В результате переменная будет хранить адрес 0, поскольку свободное место оказалось в начале оперативной памяти. Когда в следующий раз потребуется получить данные из этой переменной, процессор запросит 2 байта данных, начиная с адреса 0.

В памяти после записи число будет представлено так:

[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0]

Таким образом, вывод в консоль будет следующим:

size = 2
address = 0x000000000000
data = 1