Адресная арифметика. Пример. Тип Размер в байтах
Для указателей-переменных разрешены некоторые операции:
· присваивание;
· инкремент или декремент;
· сложение или вычитание;
· сравнение.
Физическое увеличение или уменьшение значения указателя зависит от его типа. Если к указателю, описанному как type *ptr, прибавляется, или отнимается величинаN, то значение ptr изменяется на N*sizeof(type). //Напомню, что sizeof() выдает размер в байтах. Разность двух указателей типа type* - это разность их значений, поделенная на sizeof(type).
Пример
int *ptr1 = (int*)100,*ptr2=(int*)200;
ptr1++; ptr2 - =10;
printf(“%d”,ptr2-ptr1);
_______________________________
ptr1=102; ptr2=180; ptr2-ptr1=39;
Если ptr1 и ptr2 типа long* или float*,то: ptr1=104; ptr2=160; ptr2-ptr1=14 и т. д.
Приведем таблицу основных размеров, чтобы можно было выполнять адресные вычисления:
Тип Размер в байтах
char 1
_______________________________________________________
{unsigned}int 2
{short}
_______________________________________________________
{unsigned} long 4
float
_______________________________________________________
double 8
Выполнение адресных операций ограничено. Так, сравнение указателей выполняется правильно, если они одного типа и выполнена их привязка к одним и тем же объектам данных, например - к одному и тому же массиву. В сложениях и вычитаниях используются целочисленные или адресные абсолютные выражения. Слева и справа от символа присваивания размещаются указатели (справа может быть адресное выражение) одного типа.
Массивы
Массивы в Си представлены расположенными подряд ячейками памяти, доступ к которым обеспечивается либо через индексированные переменные, либо спомощьюуказателей.
Декларация, инициализация и индексирование
В декларациях массивам может приписываться класс памяти – static, auto или extern.
Автоматические массивы инициировать нельзя. Внешние же и статические массивы можно инициировать, поместив в описании список инициирующих значений, заключенных в фигурные скобки и разделенных запятыми.
Пример
static int ndigit[] = {0, 0, 0, 0};
Под массив выделяется 4 ячейки, инициируемые 0-ми значениями.
Многомерные статические и внешние массивы также можно инициировать на основе вложенных списков в фигурных скобках.
Если явная инициация отсутствует, гарантируется, что элементы внешних и статических массивов будут иметь значение 0; автоматические массивы будут заполнены «мусором». Если инициирующих значений меньше, чем указанный размер массива, то остальные элементы получат нулевые значения. Если же значений слишком много, то это ошибка.
Пример
static double [2][3] = {{1, 2, 3}, {4, 5, 6, 7}}; // ошибка!!!
Контроль допустимости значения индекса массива в процессе выполнения программы не выполняется.
Пример
int a[10], bad;
………………
bad = a[10]; /*выход за пределы индекса не контролируется*/
Для автоматического массива большая вероятность того, что случайное значение будет занесено в ячейку bad. Для внешнего массива тоже большая вероятность такого исхода. Все зависит от того, куда адресуется индексированная переменная a[10]. Если сегмент защищен по чтению, то будет прерывание. Обычно защита только по записи.
Дата добавления: 2016-05-26; просмотров: 2082;