Главная Случайная страница


Полезное:

Как сделать разговор полезным и приятным Как сделать объемную звезду своими руками Как сделать то, что делать не хочется? Как сделать погремушку Как сделать так чтобы женщины сами знакомились с вами Как сделать идею коммерческой Как сделать хорошую растяжку ног? Как сделать наш разум здоровым? Как сделать, чтобы люди обманывали меньше Вопрос 4. Как сделать так, чтобы вас уважали и ценили? Как сделать лучше себе и другим людям Как сделать свидание интересным?


Категории:

АрхитектураАстрономияБиологияГеографияГеологияИнформатикаИскусствоИсторияКулинарияКультураМаркетингМатематикаМедицинаМенеджментОхрана трудаПравоПроизводствоПсихологияРелигияСоциологияСпортТехникаФизикаФилософияХимияЭкологияЭкономикаЭлектроника






Расположение информации в оперативной памяти. Адреса





Этот и следующий параграфы носят ознакомительный характер.

Раньше я уподоблял оперативную память тетрадному листу в клеточку. Каждая клетка - байт. Теперь я уподоблю ее многоэтажному небоскребу. Каждый этаж - байт.

Как и положено этажам, байты имеют номера. Эти номера называются адресами. Самый "нижний" байт имеет адрес 0, следующий - 1, следующий - - 2 и т.д. Если память вашего компьютера имеет объем 1 Мегабайт, то вы сами можете вычислить адрес последнего байта, учитывая, что 1 Мегабайт = 1024 Килобайта, a 1Килобайт = 1024 байта. Приняты сокращения: Мегабайт - М, Килобайт - К. Имейте в виду, что во многих книгах адреса записываются не в привычном нам виде, а в так называемой шестнадцатеричной системе счисления.

Во время выполнения вашей программы, написанной на Паскале, в памяти находится самая разная информация. То, что относится к паскалевской программе, располагается "по этажам" в следующем порядке:

 

байт с адресом 1М-1  
    куча    
   
    стек
    сегмент данных объемом 64К
      откомпилированная программа
  байт с адресом 0  

Границы между некоторыми областями памяти не фиксированы и зависят от решаемой задачи и желания программиста. В сегменте данных располагаются переменные, массивы и другие типы данных вашей программы, описанные привычным вам способом в разделах VAR, CONST и т.д. (без использования ссылок). Обратите внимание, что размер сегмента данных весьма невелик (не более 64К). Стек - область памяти, в которой располагаются данные, описанные внутри процедур (этого мы пока не делали, об этом - в Глава 13). Куча - область памяти, в которой располагаются данные, описанные при помощи ссылок.

 

Ссылки

Пусть вы хотите использовать следующий массив:

VAR a: array[1..200, 1..200] of Integer;

Давайте подсчитаем, сколько байтов в памяти займет этот массив. Одно число типа Integer занимает 2 байта. Получаем 200*200*2 = 80000 байтов. В сегменте данных массив не умещается, значит привычным образом работать с ним нельзя. Использование ссылок позволяет разместить его в куче(по английски - heap), имеющей гораздо больший размер.

Я привел лишь один из доводов в пользу применения ссылок. А поближе познакомимся мы со ссылками на простом примере. Задача: Вычислить и напечатать y=a+b, где a и b - целые числа 2 и 3. Вот традиционная программа для решения этой задачи:

VAR a, b, y: Integer;
BEGIN
a:=2; b:=3;
y:=a+b;
WriteLn (y)
END.

А теперь потребуем, чтобы число 2 и результат 5 размещались в куче (впрочем, строго говоря, не обязательно в куче). Вот программа со ссылками:

VAR b: Integer;
a,y: ^ Integer;
BEGIN
New(a); New(y);
a ^:= 2; b:=3;
y ^:= a ^ + b;
WriteLn (y ^)
END.

Пояснения: Все, что выше BEGIN, выполняется на этапе компиляции: Строка a,y: ^ Integer приказывает отвести в памяти в сегменте данных две ячейки, но не для будущих чисел 2 и 5, а для адресов ячеек из кучи, в которых эти самые 2 и 5 предполагается хранить. Итак, будущие значения a и y - не числа 2 и 5, а адреса ячеек для этих чисел или, по-другому, ссылки на ячейки для этих чисел. Пока же адреса эти не определены.

Все, что ниже BEGIN, выполняется на этапе выполнения программы: При помощи обращений к процедуре New (New(a) и New(y)) мы идем дальше и придаем переменным a и y значения конкретных адресов памяти, то есть отводим для будущих чисел 2 и 5 конкретное место в памяти. Таким образом, мы сталкиваемся с новым для нас явлением - место в памяти отводится не на этапе компиляции, а на этапе выполнения программы. В Паскале имеются средства и освобождать это место на этапе выполнения программы (процедура Dispose, на которой я не буду останавливаться). Называется все это динамическим распределением памяти и сулит выгоды экономным создателям программ, использующим большие объемы разных данных в разные моменты выполнения программы.

Оператор a ^:= 2 идет еще дальше и посылает в ячейку, адрес которой находится в ячейке a, число 2. Обозначается такая ячейка - a ^. Если бы мне вздумалось написать a:=2, это бы значило, что я хочу послать в ячейку a адрес равный двум, что вполне возможно, но синтаксически неверно, так как численные значения адресов задаются по-другому.

Смысл следующих двух операторов очевиден.

Подведем итог. Значок ^, поставленный перед типом (например, ^Integer), означает новый ссылочный тип, значения которого обязаны быть адресами переменной (или ссылками на переменную) исходного типа (в нашем случае Integer).

Значок ^, поставленный после переменной ссылочного типа (например, a^), означает переменную, на которую ссылается исходная переменная (в нашем случае исходная переменная a).

 

Вот еще некоторые возможные операции со ссылками (без особых пояснений):

TYPE D = array [1..10] of Real;
DP = ^D;
Int = ^Integer;
VAR i, j: Int; { i, j - адреса целых чисел}
m: DP; { m - адрес первой ячейки массива из 10 вещ. чисел}
BEGIN
New(i); New(j); New(m);
i^:=4;
j^:=3;
j:=i; {Теперь j и i содержат адреса одного и того же числа - 4}
WriteLn(j^); {поэтому будет напечатано число 4}
m^[9]:=300 {Девятый элемент массива становится равным числу 300}
END.

Вернемся к задаче о размещении большого массива. Поскольку Паскаль вслед за MS-DOS запрещает не только описывать, но также, естественно, и ссылаться на структуру, объемом превышающую 64К, то ссылаться сразу на весь двумерный массив не выйдет и поэтому программа получится непростой:

TYPE a = array [1..200] of Integer;
ap = ^a;
a2 = array [1..200] of ap;
VAR x: a2; {x - массив из 200 адресов (каждый - ссылка на строку из 200 элементов

исходного массива)}


BEGIN
for i:=1 to 200 do New(x[i]); {Место для массива отведено}
............
x[128]^[35]:=800; {Присвоено значение элементу массива}
.............
END.

В заключение упомяну, что ссылки полезны еще тем, что позволяют организовывать в памяти структуры переменной длины, такие как списки, деревья и т.п.

Date: 2015-09-17; view: 388; Нарушение авторских прав; Помощь в написании работы --> СЮДА...



mydocx.ru - 2015-2024 year. (0.006 sec.) Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав - Пожаловаться на публикацию