Чтение онлайн

на главную

Жанры

C# для профессионалов. Том II

Ватсон Карли

Шрифт:

Или, объединяя эти инструкции, запишем:

double [] array = new double[10];

Отметим, что размер массива задается только вместе с созданием его экземпляра. Объявление ссылки использует просто квадратные скобки для указания, что размерность (ранг) массива будет единица. В C# ранг считается частью типа массива, в отличие от числа элементов.

Ближайший эквивалент в C++ приведенного выше определения будет выглядеть так:

double *pArray = new double[10];

Эта инструкция C++ действительно дает достаточно близкую аналогию, так как обе версии C++ и C# размещаются в куче. Отметим, что версия C++ является

просто областью памяти, которая содержит 10
double
, в то время как версия C# создает экземпляр полноценного объекта. Более простая стековая версия C++:

doublе pArray[10];

не имеет аналога в C#, который использует реальный массив C#, хотя инструкция C#

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

Массивы в C# можно явно инициализировать при создании экземпляра:

double [] Array = new double[10] {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 9.0, 10.0};

Существует также более короткая форма:

double [] Array = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 9.0, 10.0};

Если массив не инициализирован явно, то будет автоматически вызываться конструктор по умолчанию для каждого из его элементов. (Элементы массива формально рассматриваются как поля-члены класса.) Это поведение отличается от C++, где не допускается никакой автоматической инициализации массивов, размещенных с помощью оператора

new
в куче (хотя C++ допускает это для массивов на основе стека).

Многомерные массивы

C# существенно отклонился от C++ в вопросе многомерных массивов, так как C# поддерживает как прямоугольные, так и неровные массивы.

Прямоугольный массив является правильной сеткой чисел. В C# это указывается синтаксисом, где запятая разделяет число элементов в каждой размерности. Например, двухмерный прямоугольный массив, можно определить следующим образом:

int [,] MyArray2d;

MyArray2d = new int[2, 3] {{1, 0}, {3, 6}, {9, 12}};

Синтаксис здесь является интуитивно понятным расширением синтаксиса одномерных массивов. Список инициализации в таком коде может отсутствовать. Например:

int [,,] MyArray3d = new int [2, 3, 2];

Это приведет к вызову конструктора по умолчанию для каждого элемента и к инициализации каждого

int
нулем. В этом частном примере проиллюстрировано создание трехмерного массива. Общее число элементов в массиве равно 2×3×2 = 12. Характеристика прямоугольных массивов состоит в том, что все строки имеют одинаковое число элементов.

Элементы прямоугольного массива доступны с помощью следующего синтаксиса.

int X = MyArray3d[1, 2, 0] + MyArray2d[0, 1];

Прямоугольный массив C# не имеет прямых аналогов в C++. Однако неровные массивы в C# соответствуют достаточно точно многомерным массивам C++. Например, если объявить в C++ массив следующим образом:

int MyCppArray[3][5];

то реально объявляется не массив 3×5, а массив массивов — массив размера 3, каждый элемент которого является массивом размера 5. Это будет, возможно, понятнее, если сделать то же самое динамически. Запишем:

int pMyCppArray = new int[3];

for (int i=0; i<3; i++) pMyCppArray[i] = new int[5];

Из

этого кода должно быть видно, что теперь не существует причины, чтобы каждая строка содержала одинаковое число элементов (хотя это вполне может быть, как в данном примере). В качестве примера неровного массива в C++, который имеет различное число элементов в каждой строке, можно написать:

int pMyCppArray = new int[3];

for (int i=0; i<3; i++) pMyCppArray[i] = new int[2*i + 2];

Соответствующие строки этого массива имеют размерности 2, 4 и 6. C# делает те же самые вещи почти таким же образом, хотя в случае C# синтаксис указывает число размерностей более явно:

int[][] MyJaggedArray = new int[3][];

for (int i = 0; i < 3, i++) MyJaggedArray[i] = new int[2*i + 2];

Доступ к членам неровного массива следует точно тому же синтаксису, что и в C++.

int X = MyJaggedArray[1][3];

Здесь показан неровный массив ранга 2. Однако так же, как и в C++, можно определить неровный массив с любым рангом, необходимо просто добавить прямоугольные скобки в его определение.

Проверка границ

Одной из областей, где объектная сущность массивов C# становится явной, является проверка границ. Если обратиться к элементу массива C#, указывая индекс, который не находится в границах массива, то это будет обнаружено во время выполнения и породит исключение

IndexOutOfBoundsException
. В C++ этого не происходит, в результате появляются трудноуловимые ошибки. C# выполняет дополнительную проверку ошибок за счет производительности. Хотя можно было бы ожидать, что это создаст потерю производительности, на самом деле здесь содержится преимущество, так как среда выполнения .NET способна контролировать код, чтобы гарантировать, что он является безопасным в том смысле, что не будет пытаться обратиться к памяти, которая не выделена для его переменных. Это обеспечивает выигрыш производительности, так как различные приложения могут, например, выполняться в одном процессе, и все равно есть уверенность, что эти приложения будут изолированы друг от друга. Имеется также выигрыш и в безопасности, так как возможно более точное предсказание, что данная программа будет или не будет пытаться делать.

С другой стороны, теперь нет ничего необычного в том, что программисты C++ используют какой-либо из различных классов оболочек массивов в стандартной библиотеке или в MFC, в основном для линейных массивов, чтобы получить тот же контроль границ и различные другие свойства, хотя в этом случае — без выигрыша в безопасности и производительности, связанных с возможностью анализа программы до ее выполнения.

Изменение размера массивов

Массивы C# являются динамическими, то есть можно определить число элементов в каждой размерности во время компиляции (также, как в динамически выделяемых массивах в C++). Однако невозможно изменить их размер после того, как были созданы их экземпляры. Если требуется это сделать, необходимо рассмотреть другие связанные с этим классы в пространстве имен

System.Collections
в библиотеке базовых классов, таких как
System.Collections.ArrayList
. Однако в этом отношении C# не отличается от C++. Обычные массивы C++ не допускают изменение размера, но существует ряд классов стандартной библиотеки, которые предоставляют это свойство.

Поделиться:
Популярные книги

Идеальный мир для Лекаря 6

Сапфир Олег
6. Лекарь
Фантастика:
фэнтези
юмористическая фантастика
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 6

Дракон с подарком

Суббота Светлана
3. Королевская академия Драко
Любовные романы:
любовно-фантастические романы
6.62
рейтинг книги
Дракон с подарком

Темный Патриарх Светлого Рода 6

Лисицин Евгений
6. Темный Патриарх Светлого Рода
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Темный Патриарх Светлого Рода 6

Падение Твердыни

Распопов Дмитрий Викторович
6. Венецианский купец
Фантастика:
попаданцы
альтернативная история
5.33
рейтинг книги
Падение Твердыни

Сержант. Назад в СССР. Книга 4

Гаусс Максим
4. Второй шанс
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Сержант. Назад в СССР. Книга 4

Измена. Право на сына

Арская Арина
4. Измены
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Измена. Право на сына

Метка драконов. Княжеский отбор

Максименко Анастасия
Фантастика:
фэнтези
5.50
рейтинг книги
Метка драконов. Княжеский отбор

На границе тучи ходят хмуро...

Кулаков Алексей Иванович
1. Александр Агренев
Фантастика:
альтернативная история
9.28
рейтинг книги
На границе тучи ходят хмуро...

Ученичество. Книга 1

Понарошку Евгений
1. Государственный маг
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Ученичество. Книга 1

Энфис 2

Кронос Александр
2. Эрра
Фантастика:
героическая фантастика
рпг
аниме
5.00
рейтинг книги
Энфис 2

Не верь мне

Рам Янка
7. Самбисты
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Не верь мне

Вечная Война. Книга II

Винокуров Юрий
2. Вечная война.
Фантастика:
юмористическая фантастика
космическая фантастика
8.37
рейтинг книги
Вечная Война. Книга II

Неудержимый. Книга III

Боярский Андрей
3. Неудержимый
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Неудержимый. Книга III

Энфис 6

Кронос Александр
6. Эрра
Фантастика:
героическая фантастика
рпг
аниме
5.00
рейтинг книги
Энфис 6