ТОР 5 статей: Методические подходы к анализу финансового состояния предприятия Проблема периодизации русской литературы ХХ века. Краткая характеристика второй половины ХХ века Характеристика шлифовальных кругов и ее маркировка Служебные части речи. Предлог. Союз. Частицы КАТЕГОРИИ:
|
Указатели и массивыВ Си существует самая тесная связь между указателями и массивами, поэтому лучше эти средства рассматривать вместе. Как мы знаем, структура массива полностью соответствует структуре оперативной памяти – элементы массива занимают в ней подряд идущие ячейки. Значит, если описан массив int mass[5]; то в оперативной памяти для его элементов выделяется пять подряд идущих ячеек: К i -му элементу этого массива можно обратиться, назвав его индекс: mass[i]. Доступ к любому элементу массива, осуществляемый по его индексу (номеру), может быть выполнен при помощи указателя, причем это будет сделано быстрее. Опишем переменную ptr как указатель на данные целого типа: int *ptr; В результате присваивания ptr = &mass[0]; эта переменная будет содержать адрес начального (нулевого) элемента этого массива, то есть указатель ptr будет указывать на элемент mass[0]: Адрес начального элемента любого массива называется базовым адресом этого массива. Таким образом, сейчас указатель ptr содержит базовый адрес массива mass. Если увеличить значение указателя на единицу, то ptr + 1 будет указывать на следующий элемент массива, то есть на mass[1], ptr + 2 – на элемент mass[2] и так далее. В общем случае, если значение указателя увеличить на k, то можно получить адрес k -го элемента массива mass. Значит, адрес любого элемента массива равен сумме его базового адреса, который является адресом его начального элемента, и смещения этого элемента от начала массива. Для начального (нулевого) элемента массива это смещение равно нулю, для первого элемента – единице, для второго – двум, для k -го оно равно k. Это верно для массива любого типа. Смысл выражения «увеличить указатель ptr на единицу», как и смысл любой арифметики с указателями, заключается в том, что ptr + 1 указывает на следующий за ptr элемент, а ptr + k – на k -й после ptr элемент массива. Между индексированием элементов массива и арифметикой с указателями существует очень тесная связь, потому что имя любого массива в Си есть адрес его начального элемента, то есть имя массива является его базовым адресом. Значит, ptr = &mass[0]; можно записать в другом виде: ptr = mass; Это будет одно и то же: записи &mass[0] и mass эквивалентны. Из всего этого следует, что в общем случае запись &mass[k] будет эквивалентна записи (mass + k), а сам k -й элемент массива можно определить как mass[k] или как *(mass + k). С другой стороны, если ptr – указатель, то в выражениях его можно использовать с индексом, то есть запись ptr[k] эквивалентна записи *(ptr + k). Таким образом, элемент массива в Си разрешается изображать и в виде указателя со смещением, и в виде имени массива с индексом. Между именем массива и указателем, выступающим в роли имени массива, однако существует различие. Указатель – это переменная, поэтому можно записать ptr = mass или ptr++. Но имя массива не является переменной, и записи типа mass = ptr или mass++ не допускаются. Помимо рассмотренной операции сложения, над указателями можно выполнять следующие операции: - складывать и вычитать указатели и целые данные, - вычитать и сравнивать два указателя, ссылающиеся на элементы одного и того же массива, - присваивать значение указателя другому указателю того же типа, - присваивать указателю нуль и сравнивать его с нулем. Над указателями нельзя выполнять следующие операции: - складывать два указателя, перемножать их, делить, сдвигать, выделять разряды, - складывать указатели со значениями типа float и double, - присваивать указателю одного типа значение указателя другого типа (исключение составляют указатели типа void). Указатели можно использовать и при работе с многомерными массивами: int trio[5][2][3]; int *i_ptr; Описан трехмерный массив trio целого типа и указатель ptr на данные целого типа. Присвоим этому указателю значение базового адреса массива: i_ptr=&trio[0][0][0]; Необходимо учесть, что для многомерных массивов нельзя использовать операцию присваивания базового адреса указателю в виде i_ptr=trio; как это имеет место для векторов (одномерных массивов). Доступ к j -му элементу i -й строки k -го слоя массива trio может быть осуществлен либо с помощью индексов: trio[k][i][j]=1; либо с помощью указателей: *(i_ptr + k*(2*3) + i*3 + j)=1; Как и в Паскале, в языке Си запрещается присваивать значения элементов одного массива другому массиву целиком: float r[2][2], s[2][2]; r = s; // ошибка! Эти ограничения можно обойти с помощью указателя: float *f_ptr; f_ptr = &s[0][0]; r = *f_ptr; При этом элементам массива r будут присвоены значения соответствующих элементов массива s. Не нашли, что искали? Воспользуйтесь поиском:
|