ТОР 5 статей: Методические подходы к анализу финансового состояния предприятия Проблема периодизации русской литературы ХХ века. Краткая характеристика второй половины ХХ века Характеристика шлифовальных кругов и ее маркировка Служебные части речи. Предлог. Союз. Частицы КАТЕГОРИИ:
|
Связь с указателямиПо определению операция индексирования «[]» интерпретируется так, что e1[e2] эквивалентно *((e1) + (e2)). Здесь внутренние скобки указывают, что вначале выполняются все операции внутри e1 и e2, затем + и затем *. Если e1 имя массива и e2 значение целого типа, то выражение выполняется в соответствии с правилами адресной арифметики, т.е. с учетом типа. Пример float a[20]; …………………….. …a[5]….. Если a соответствует адресу, например, 100, то a[5] извлекает 4 байта, расположенных с адреса 100 + 5*4 = 120. Если е - многомерный массив и задано в определении: тип е[n1][n2]…[nm]; и если е появляется где-либо в выражении, то эта запись преобразовывается в адрес самого первого элемента массива, что эквивалентно записи &e[0][0]…[0] (индексы повторяются m раз). Запись вида e[i] преобразуется в ссылку на (m-1) – мерный массив, а именно: e[i] эквивалентно записи (e + i), что в результате дает адрес равный: e + i x n2 x … x nm x sizeof(тип). Фактически это эквивалентно записи: &e[i][0]…[0] (0-е индексы повторяются m-1раз) Добавим еще один индекс, чтобы понять принцип расчета. Запись в выражении вида e[i][j] преобразуется в ссылку на (m-2) мерный массив, что дает адрес равный:
e + i x n2 x … x nm x sizeof(тип)+j x n3 x … x nm x sizeof(тип) И это эквивалентно записи: &e[i][j][0]…[0] (0-й индекс повторяется m-2 раз). Исчерпание всех индексов означает получение доступа к 0-мерному массиву и это конкретное значение в ячейке, а не адрес. Пример float array[2][5]; Указанные записи в выражениях эквивалентны: 1) array, &array[0][0] 2) array[i], (array+i).
Эффективность доступа через индексы и через указатели приблизительно одинакова, но в последнем случае программа иногда короче и в ряде случаев можно обойтись без дополнительных переменных. Пример Обоснованный пример использования указателей вместо индексов. Выделяется память по запросам – функция alloc(n) //n – запрашивающий размер; функция free(p) – освобождает память, на которую ссылается указатель. #define NULL 0 /*значение ошибки*/ #define ALLOCSIZE 100/*объем доступной памяти*/ static char allocbuf[ALLOCSIZE];/* непрерывная память*/ static char *allocp=allocbuf;/*указатель на свободное место*/ char *alloc(n) /*выдача сc на n байт*/ int n; { if (allocp+n<=allocbuf+ALLOCSIZE){ /*?есть место*/ allocp+=n; return (allocp-n); } else return (NULL); /*места нет*/ } free(p); /*возврат памяти сс р*/ char *p; { if (p>=allocbuf&&p<allocbuf+ALLOCSIZE) allocp=p; } Такая программа может работать правильно, если возвращается всегдапоследовательный выделенный кусок памяти. Проверки вида if(allocp+n<=allocbuf+ALLOCSIZE) “хватит ли места для запроса” и if(p>=allocbuf&&p<allocbuf+ALLOCSIZE) “попадание ссылки в заданный диапазон” для указателей будут выполняться правильно, если ссылки формируются относительно общего базового адреса, в данном случае это один и тот же массив. Мы не рассматриваем особенности сравнения указателей для различных их модификаций с учетом моделей памяти. Не нашли, что искали? Воспользуйтесь поиском:
|