Шаг 52.
Язык программирования C#. Начала
Массивы. Операции с массивами

    На этом шаге мы рассмотрим особенности присваивания массивов.

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

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace pr52_1
{
    class Program
    {
        static void Main()
        {
            // Целочисленный массив: 
            int[] A = {1, 3, 5, 7, 9};
            // Переменные массива: 
            int[] B, C;

            // Присваивание массивов:
            B = A;

            // Создание нового массива:
            C = new int [A.Length];

            // Поэлементное копирование массива: 
            for(int k = 0; k < A.Length; k++){
                C[k] = A[k];
            }

            // Изменение значения первого элемента в массиве А:
            A[0] = 0;
            // Изменение значения последнего элемента 
            //в массиве В:
            B[B.Length-1] = 0;

            // Сообщение в консольном окне:
            Console.WriteLine("A:\tB:\tC:");
            // Отображение содержимого массивов: 
            for (int k = 0; k < A.Length; k++)
            {
                // Отображение значений элементов массивов:
                Console.WriteLine("{0}\t{1}\t{2}", A[k], B[k], C[k]);
            }
            // Задержка:
            Console.ReadLine();
        }
    }
}
Архив проекта можно взять здесь.

    Результат выполнения программы приведен на рисунке 1.


Рис.1. Результат работы приложения

    В программе командой

  int[] A = {1, 3, 5, 7, 9};
создается и инициализируется целочисленный массив А из 5 элементов (значения - нечетные числа от 1 до 9 включительно). А вот командой
  int[] B, C;
объявляются две переменные массива (но сами массивы не создаются!). Переменные В и С в силу того, как они объявлены (идентификатором типа указано выражение int[]), могут ссылаться на одномерные целочисленные массивы. Значение переменной В присваивается командой
  B = A;    . 
Но копирования массива А в данном случае не происходит. Чтобы понять, каковы последствия команды
  B = A;    ,
следует учесть, что в действительности значением переменной массива является ссылка или адрес массива. Поэтому значение переменной А - это адрес массива, на который ссылается переменная. Этот адрес копируется в переменную В. Как следствие, переменная В будет ссылаться на тот же массив, на который ссылается переменная А. Это важный момент: при выполнении команды
  B = A;    
новый массив не создается. И переменная А, и переменная В будут ссылаться на физически один и тот же массив.

    Иначе мы поступаем с переменной С. Командой

  C = new int [A.Length];
создается новый пустой массив, и ссылка на этот массив записывается в переменную С. Размер созданного массива определяется выражением A.Length, и поэтому он такой же, как у массива А. Затем с помощью конструкции цикла выполняется поэлементное копирование (команда
  С[k] = А[k]; 
в теле цикла) содержимого массива А в массив С. В результате мы получаем, что переменные А и С ссылаются на одинаковые массивы, но это все же два отдельных массива (хотя и с совпадающими значениями элементов).

    При выполнении команды

  А[0] = 0 
в массиве, на который ссылается переменная А (и переменная В), значение первого элемента меняется с 1 на 0. При выполнении команды
  В[В.Length-1] = 0 
значение последнего элемента в массиве, на который ссылается переменная В (и переменная А), меняется с 9 на 0. Но в массиве С все элементы остались с теми же значениями, которые у них были в самом начале после поэлементного копирования. В частности, первый элемент остался со значением 1, а последний элемент остался со значением 9. Это подтверждает результат выполнения программы.


В команде
  Console.WriteLine("{0}\t{1}\t{2}", A[k], B[k], C[k]);
в текстовом литерале использована инструкция табуляции \t. Инструкция обрабатывается так. При отображении текста в консоли каждый символ отображается в определенной позиции. Они идут подряд одна за другой. Среди них есть особые "реперные" - как правило, через каждые восемь позиций. То есть "реперными" является 1-я, 9-я, 17-я, 25-я позиция и так далее. Если при отображении текста встречается инструкция \t, то следующий символ будет отображаться в ближайшей реперной позиции (вправо от позиции последнего отображенного символа). На практике применение инструкции табуляции \t позволяет выполнять выравнивание по столбикам.

    В теле конструкции цикла, в котором отображаются значения элементов массивов А, В и С (точнее, массивов, на которые ссылаются указанные переменные - поскольку массивов всего два), использована команда

  Console.WriteLine("{0}\t{1}\t{2}", A[k], B[k], C[k]);    .
При отображении текстовой строки, указанной первым аргументом метода WriteLine(), вместо инструкции {0} подставляется значение элемента А[k] (при заданном значении индекса k), вместо инструкции {1} подставляется значение элемента В[k], а вместо инструкции {2} подставляется значение элемента С[k]. После отображения первого и второго значения выполняется табуляция. В итоге значения элементов массива, на который ссылается переменная А, отображаются в столбике под надписью "А:". Под надписью "В:" в столбик отображаются значения элементов массива, на который ссылается переменная В. А под надписью "С:" в столбик отображаются значения элементов массива, на который ссылается переменная С.

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

    На следующем шаге мы продолжим изучение этого вопроса.




Предыдущий шаг Содержание Следующий шаг