Адресная арифметика

Для указателей-переменных разрешены некоторые операции:

· присваивание;

· инкремент или декремент;

· сложение или вычитание;

· сравнение.

Физическое увеличение или уменьшение значения указателя зависит от его типа. Если к указателю, описанному как 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; просмотров: 1681; ЗАКАЗАТЬ НАПИСАНИЕ РАБОТЫ


Поиск по сайту:

Воспользовавшись поиском можно найти нужную информацию на сайте.

Поделитесь с друзьями:

Считаете данную информацию полезной, тогда расскажите друзьям в соц. сетях.
Poznayka.org - Познайка.Орг - 2016-2022 год. Материал предоставляется для ознакомительных и учебных целей.
Генерация страницы за: 0.011 сек.