Страница 330 из 502
В C# указатели и массивы связаны друг с другом. Например, при указании имени массива без индекса в операторе с модификатором fixed формируется указатель на начало массива. В качестве примера рассмотрим следующую программу.
<b>/* Указание имени массива без индекса приводит к формированию указателя на начало массива. */</b>
<b>using System;</b>
<b>class PtrArray {</b>
<b> unsafe static void Main() {</b>
<b> int[] nums = new int[10];</b>
<b> fixed(int* p = &nums[0], p2 = nums) {</b>
<b> if(p == p2)</b>
<b> Console.WriteLine("Указатели p и p2 содержат " +</b>
<b> "один и тот же адрес.");</b>
<b> }</b>
<b> }</b>
<b>}</b>
Ниже приведен результат выполнения этой программы.
<b>Указатели р и р2 содержат один и тот же адрес</b>
Как следует из приведенного выше результата, выражения
<b>&nums[0]</b>
И
<b>nums</b>
оказываются одинаковыми. Но поскольку вторая форма более лаконична, то она чаще используется в программировании, когда требуется указатель на начало массива.
Когда указатель обращается к массиву, его можно индексировать как сам массив. Такой синтаксис служит более удобной в некоторых случаях альтернативой арифметическим операциям над указателями. Рассмотрим следующий пример программы.
<b>// Проиндексировать указатель как массив.</b>
<b>using System;</b>
<b>class PtrlndexDemo {</b>
<b> unsafe static void Main() {</b>
<b> int[] nums = new int[10];</b>
<b> // Проиндексировать указатель.</b>
<b> Console.WriteLine("Индексирование указателя как массива.");</b>
<b> fixed (int* p = nums) {</b>
<b> for (int i = 0; i < 10; i++)</b>
<b> p[i] = i; // индексировать указатель как массив</b>
<b> for (int i = 0; i < 10; i++)</b>
<b> Console.WriteLine("p[{0}]: {1} ", i, p[i]);</b>
<b> }</b>
<b> // Использовать арифметические операции над указателями.</b>
<b> Console.WriteLine("nПрименение арифметических " +</b>
<b> "операций над указателями.");</b>
<b> fixed (int* p = nums) {</b>
<b> for (int i = 0; i < 10; i++)</b>
<b> *(p + i) = i; // использовать арифметическую операцию над указателем</b>
<b> for (int i = 0; i < 10; i++)</b>
<b> Console.WriteLine("*(p+{0}): {1} ", i, *(p + i));</b>
<b> }</b>
<b> }</b>
<b>}</b>
Ниже приведен результат выполнения этой программы.
<b>Индексирование указателя как массива. </b>
<b>Р[0] : 0 </b>
<b>Р[1] : 1 </b>
<b>Р[2] : 2 </b>
<b>Р[3] : 3 </b>
<b>Р[4] : 4 </b>
<b>Р[5] : 5 </b>
<b>Р[6] : 6 </b>
<b>Р[7] : 7 </b>
<b>Р[8] : 8 </b>
<b>Р[9] : 9 </b>
<b>Применение арифметических операций над указателями. </b>
<b>*(р+0) : 0 </b>
<b>*(P+1) : 1 </b>
<b>*(р+2) : 2 </b>
<b>*(р+3) : 3 </b>
<b>*(р+4) : 4 </b>
<b>*(р+5) : 5 </b>
<b>*(р+6) : 6 </b>
<b>*(р+7) : 7 </b>
<b>*(р+8) : 8 </b>
<b>*(р+9) : 9 </b>
Как следует из результата выполнения приведенной выше программы, общая форма выражения с указателем
<b>*(ptr + i)</b>
может быть заменена следующим синтаксисом индексирования массива.
<b>ptr[i]</b>
Что касается индексирования указателей, то необходимо иметь в виду следующее. Во-первых, при таком индексировании контроль границ массива не осуществляется. Поэтому указатель может обращаться к элементу вне границ массива. И во-вторых, для указателя не предусмотрено свойство Length, определяющее длину массива. Поэтому, если используется указатель, длина массива заранее неизвестна.