Добавить в цитаты Настройки чтения

Страница 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 = &amp;nums[0], p2 = nums) {</b>

<b>      if(p == p2)</b>

<b>        Console.WriteLine(&quot;Указатели p и p2 содержат &quot; +</b>

<b>                 &quot;один и тот же адрес.&quot;);</b>

<b>    }</b>

<b>  }</b>

<b>}</b>

Ниже приведен результат выполнения этой программы.

<b>Указатели р и р2 содержат один и тот же адрес</b>

Как следует из приведенного выше результата, выражения

<b>&amp;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(&quot;Индексирование указателя как массива.&quot;);</b>

<b>    fixed (int* p = nums) {</b>

<b>      for (int i = 0; i &lt; 10; i++)</b>

<b>        p[i] = i; // индексировать указатель как массив</b>

<b>      for (int i = 0; i &lt; 10; i++)</b>

<b>        Console.WriteLine(&quot;p[{0}]: {1} &quot;, i, p[i]);</b>

<b>    }</b>

<b>    // Использовать арифметические операции над указателями.</b>

<b>    Console.WriteLine(&quot;nПрименение арифметических &quot; +</b>

<b>          &quot;операций над указателями.&quot;);</b>

<b>    fixed (int* p = nums) {</b>

<b>      for (int i = 0; i &lt; 10; i++)</b>

<b>        *(p + i) = i; // использовать арифметическую операцию над указателем</b>

<b>      for (int i = 0; i &lt; 10; i++)</b>

<b>        Console.WriteLine(&quot;*(p+{0}): {1} &quot;, 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, определяющее длину массива. Поэтому, если используется указатель, длина массива заранее неизвестна.