На этом шаге мы рассмотрим связь указателей и массивов.
Указатели в языке C# тесно связаны с массивами. Точнее, при работе с массивами весьма эффектно могут использоваться указатели. Чтобы понять, почему такое возможно, необходимо учесть несколько обстоятельств. А именно:
Зная имя массива, мы можем получить доступ к области памяти, в которую записан первый (начальный) элемент. Поскольку элементы массива расположены подряд, то, индексируя указатель (или выполняя иные операции адресной арифметики), мы можем получить доступ к любому элементу массива. Правда автоматического контроля на предмет выхода за пределы массива уже не будет. Инструкция fixed в данном случае нужна для того, чтобы гарантировать неизменность места размещения массива в памяти (это позволяет избежать перемещения массива при оптимизации использования ресурсов). Небольшой пример, в котором совместно используются указатель и массив, представлен в примере ниже.
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace pr212_1 { // Класс с главным методом: class Program { // Главный метод: unsafe static void Main() { // Размер массива: int size = 10; // Объявление указателя: int* q; // Создание массива: int[] nums = new int[size]; Console.WriteLine("Заполнение массива:"); // Используем fixed-блок: fixed(int* p = nums){ // Указателю присваивается значение: q = p + size - 1; // Перебор элементов массива: for(int k = 0; k < nums.Length; k++){ // Элементу массива присваивается значение: p[k] = k + 1; // Отображение значения элемента массива: Console.Write("|" + nums[k]); } Console.WriteLine("|"); // Перебор элементов массива с помощью указателя: while(p <= q) { // Возведение значения элемента в квадрат: (*q) *= (*q); // Изменение значения указателя: q--; } } // Отображение содержимого массива: Console.WriteLine("Maссив после изменения:"); for(int k = 0;k < nums.Length; k++){ // Отображение значения элемента: Console.Write("|" + nums[k]); } Console.WriteLine("|"); } } }
Как выглядит результат выполнения программы, показано ниже:
Рис.1. Результат выполнения программы
В этой программе мы создаем целочисленный массив nums. Размер массива определяется переменной size (значение 10). Также мы объявляем указатель q на целочисленное значение. Затем используется fixed-блок, в котором объявляется указатель p на целое число, а значением указателю присваивается имя массива nums. Поскольку имя массива является указателем на начальный элемент массива, то указатель p ссылается на этот же начальный элемент. Командой
q = p + size - 1;
Для заполнения массива использована конструкция цикла for, в котором индексная переменная k последовательно принимает значения индексов элементов массива nums. При этом значения элементам массива присваиваются командой
p[k] = k + 1; .
Еще раз элементы массива перебираются с помощью цикла while. Эта конструкция цикла выполняется, пока истинно условие p<=q (адрес в указателе p не превышает адрес в указателе q).
За каждый цикл командой
(*q) *= (*q);
q--;
На следующем шаге мы рассмотрим связь указателей и текста.