Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Ответы по дисциплине АОП.docx
Скачиваний:
66
Добавлен:
24.04.2019
Размер:
2.91 Mб
Скачать

Адресация памяти

  • Будем считать, что оперативная память компьютера представляет собой линейную последовательность пронумерованных ячеек памяти – байтов и каждая ячейка памяти имеет адрес.

  • Б удем также считать, что компьютер имеет 32-разрядную архитектуру и адреса записываются как 32-битные коды.

  • Наименьший адрес: 0x00000000, наибольший – 0xFFFFFFFF.

  • Адресуемый объем памяти – 232 байт = 4 Гбайт

Адреса объектов программы

  • Каждый объект программы занимает определенный участок оперативной памяти компьютера и, следовательно, может быть охарактеризован адресом начала этого участка, который и считается адресом данного объекта.

  • В языке С имеется специальная унарная операция & для получения адреса объекта d в оперативной памяти.

Функция printf имеет специальный формат %p для вывода адреса.

Вопрос №46. Размещение в памяти объектов программы. Размеры участков памяти, выделяемые объектам программы.

# include <stdio.h>

#include <stdlib.h>

int x;

short y;

char a[256], b[512];

Int fact(int n) {

return n ? n * fact(n-1) : 1;

}

main() {

printf("addr(x) = %p\n", &x);

printf("addr(y) = %p\n", &y);

printf("addr(a) = %p\n", &a);

printf("addr(b) = %p\n", &b);

printf("addr(fact) = %p\n", &fact);

system("PAUSE");

return 0;

}

О размерах участков памяти, выделяемых объектам

Результаты работы программы позволяют предположить, что память объектам программы выделяется блоками, кратными 16 байт.

Вопрос №47. Адреса массивов и функций.

Некоторые объекты программы не требуют применения к ним операции взятия адреса &, т.к. они сами и являются адресами.

К их числу относятся функции и массивы, т.е. значением имени функции и значением имени массива является адрес.

Доказательство этого:

Вопрос №48. Адресная арифметика. Правила адресной арифметики.

Можно предположить, что адреса являются обычными числами (?) и могут участвовать в арифметических операциях.

Правила адресной арифметики

  1. К адресу можно прибавлять или из адреса можно вычитать целые значения. При этом результат операции зависит от типа переменной, адрес которой участвует в операции. Если для данного типа размер переменной равен n байт и к адресу прибавляется i, то величина адреса изменится на i*n.

  2. Никакие другие операции к адресам неприменимы, т.Е. Адреса нельзя умножать, делить, складывать между собой и пр.

  3. Исключением является операция вычитания адресов однотипных объектов, результатом которой является целое число, равное количеству объектов данного типа, которые могут разместиться на участке памяти между адресами-операндами.

Вопрос №49. Указатели. Нетипизированные указатели.

Адреса объектов программы можно сохранять в переменных специального вида указателях.

Указатели образуют не один конкретный тип данных (хотя все указатели имеют один размер – 4 байта); типов указателей существует столько, сколько существует типов данных, т.е. для любого типа данных Т существует тип указателя Т*.

Примеры типов указателей: char*, int*, short*, long*, float*, double*, void*, …

Указатели типа void* называются нетипизированными указателями. При выполнении арифметических операций над такими указателями считается, что объекты, на которые они указывают, имеют размер 1 байт.

Вопрос №50. Операция доступа (ссылки) по указателю.

  • В языке С существует одноместная операция * , применяемая к значениям, являющимся адресами (указателями). Результатом этой операции является объект программы, расположенный по данному адресу. Эта операция называется операцией ссылки по указателю, или операцией разыменования.

  • Операции & и * являются взаимно-дополняющими и, если они расположены подряд, взаимно компенсируют друг друга:

  • Пусть дано определение: int x; Тогда &x – адрес x; *&x – сама переменная x; &*&x – адрес x и т.д.

  • Переменная типа указатель может в разное время принимать различные значения. Следовательно, через одну и туже переменную-указатель можно обращаться к разным переменным (в разное время):

int a=2, b=3, c=4;

int* p=&a;

*p=7;

p=&b; *p=8;

p=&c; *p=9;

printf(“a=%d, b=%d, c=%d\n”, a, b, c); //a=7, b=8, c=9

Вопрос №51. Указатели и массивы.

Массив - это одна из наиболее простых структур данных, представляющих собой линейную последовательность фиксированного количества однотипных элементов, расположенных в памяти друг за другом непрерывно и допускающих прямой доступ к любому элементу по его номеру (индексу).

Массив характеризуется именем, типом элементов и их количеством.

Пример определения массива: int x[50]

В языке С существует очень тесная связь между массивами и указателями, которая характеризуется простым утверждением: