Главная | Обратная связь | Поможем написать вашу работу!
МегаЛекции

Тема 5. 3 Обработка массивов и адресная арифметика




 

Указатели позволяют эффективно организовать работу с массивами. Фактически, обозначение массива представляет собой скрытую форму использования указателей. Например, имя массива является указателем на его первый элемент, т. е. если аггау[100] - массив из ста элементов, то

array == & аггау[0]

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

int array[100];

int *arr_ptr;

arr_ptr = array;

В данном примере указатель arr_ptr указывает на первый элемент массива array. Интересным является тот факт, что значение указателя- переменной можно изменять. Отметим, что речь идет о значении самого указателя, а не ячейки, на которую он указывает.

Предположим, что первый элемент массива array размечен по адресу 56000. После присвоения указатель arr_ptr указывает на первый элемент, т. е. на адрес 56000. Соответственно, и значение указателя arr_ptr равно 56000:

arrptr == 56000

Если необходимо записать число 12 в первую ячейку массива, то это можно сделать следующими способами:

array [0] = 12;

arr_ptr[0] =12;

*arr_ptr = 12;

Теперь предположим, что необходимо записать число 13 во вторую ячейку массива array. Это можно выполнить одним из следующих способов:

аггау[1] - 13; arr_ptr[l] - 13;

*(arr_ptr + 1) = 13;

Интерес представляет последняя строка. Здесь была показана арифметическая операция над значением указателя-переменной. Последнюю строку также можно было заменить следующими двумя строками: arr_ptr++;

*arr_ptr =13;

Разница заключается в том, что в последнем варианте изменения значения переменной-указателя сохранились. В этом нет ничего нового, все по аналогии с переменными целого типа: выражение х + 1 не меняет значения переменной х, в то время как х++ увеличивают значение переменной х на единицу.

В рассматриваемом примере после увеличения значение переменной-указателя будет равно 56002. Это связано с тем, что добавляется не число один, а единица памяти, т. е. количество байт, необходимых для хранения данных определенного типа. Тип данных в нашем случае - int, и количество байт для одной ячейки памяти равно двум. Если бы мы работали с указателем типа float, то значение переменной-указателя стало бы равно 56004, поскольку числа с плавающей точкой требуют для хранения четыре байта.

Массивы и указатели тесно взаимосвязаны. Указатель может использоваться для определения определенного элемента массива, а также для получения его значения:

array + 2 == & array[2] // один и тот же адрес *(аггау + 2) == аггау[2] // одно и то же значение

Кстати, выражения * (array + 2) и * array + 2 имеют разный смысл. Операция имеет более высокий приоритет, чем " +", поэтому последнее выражение означает (*аггау) + 2:

* (array + 2) // значение третьего элемента массива array

* array + 2 //к значению первого элемента добавляется число два

Рассмотрим пример, иллюстрирующий вывод на экран значений массива. Перебор элементов массива будет осуществляться с помощью переменной-указателя. Воспользуемся уже объявленными массивом array из 100 элементов и указателем arrjptr. Предположим, что массив уже содержит какие-то данные.

arr_ptr = array; II пусть указатель указывает на первый элемент массива for(i = 0; i< =" " p=" " >

В данном случае происходит увеличение значения указателя, т. е. на каждом цикле указатель продвигается по массиву на один элемент. Таким же образом можно уменьшать значение указателя, двигаясь по массиву в обратную сторону.

Однако при таком перемещении необходимо соблюдать осторожность. Компьютер не следит за тем, ссылается ли указатель на массив или уже нет. Возникает опасность выйти за рамки массива.

Кроме того, оператор увеличения (уменьшения) можно использовать только для переменных типа указатель, но не для констант, подобно тому, как нельзя применять оператор увеличения для обычных констант. Так в последнем примере при попытке выполнить операцию аггау++ будет выдано сообщение об ошибке.

В языке Си существует возможность находить разность между двумя указателями. Обычно это применяется при работе с указателями, ссылающимися на элементы одного и того же массива, чтобы определить на каком расстоянии друг от друга находятся элементы.

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

int zippo [4] [2]; int *р;

Тогда р = zippo

указывает на первый элемент первой строки, т. е.: р == zippo == & zippo[0][0]

Чтобы ответить на вопрос, на что указывает р++ на zippo[0][l] или zippo[l][0], необходимо знать, как располагается в памяти двухмерный массив. Он размещается, подобно одномерным массивам, занимая последовательные ячейки памяти. Порядок элементов определяется тем, что самый правый индекс массива изменяется первым, т. е. элементы массива располагаются следующим образом:

zippo[0][0] zippo[0][l] zippo[l][0] zippo[l][l] zippo[2][0]...

Таким образом, в нашем примере: р == & zippo[0][0] // первая строка первый столбец

р + 1 = & zippo[0][l] // первая строка второй столбец р + 2 = & zippo[l][0] // вторая строка первый столбец р + 3 == & zippo[l][l] // вторая строка второй столбец

Двухмерный массив можно рассматривать как массив массивов. В этом случае, zippo является именем двухмерного массива, но четыре строки, являющиеся массивами из двух элементов, также имеют свои имена. Имя первой строки zippo[0], второй - zippo[l] и т. д. Имя массива является указателем на массив в том смысле, что оно ссылается на первый его элемент:

zippo [0] == & zippo[0][0] zippo[l] == & zippo[l][0] zippo [2] == & zippo[2][0] zippo[3] == & zippo[3][0]

 

Поделиться:





Воспользуйтесь поиском по сайту:



©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...