Студопедия — Obsolete 7 страница
Студопедия Главная Случайная страница Обратная связь

Разделы: Автомобили Астрономия Биология География Дом и сад Другие языки Другое Информатика История Культура Литература Логика Математика Медицина Металлургия Механика Образование Охрана труда Педагогика Политика Право Психология Религия Риторика Социология Спорт Строительство Технология Туризм Физика Философия Финансы Химия Черчение Экология Экономика Электроника

Obsolete 7 страница






Для каждого адреса, вычисленного инициализатором_указателя_fixed, оператор fixed гарантирует, что переменная, находящаяся по этому адресу, не подлежит перемещению или удалению сборщиком мусора на время действия оператора fixed. Например, если адрес, вычисленный инициализатором_указателя_fixed, ссылается на поле объекта или на элемент экземпляра массива, оператор fixed гарантирует, что содержащий экземпляр объекта не будет перемещен или удален в течение срока жизни этого оператора.

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

Фиксированные объекты могут вызвать фрагментацию кучи (поскольку их нельзя перемещать). По этой причине объекты следует фиксировать только при абсолютной необходимости и на как можно более короткий срок.

Пример:

class Test
{
static int x;
int y;

unsafe static void F(int* p) {
*p = 1;
}

static void Main() {
Test t = new Test();
int[] a = new int[10];
unsafe {
fixed (int* p = &x) F(p);
fixed (int* p = &t.y) F(p);
fixed (int* p = &a[0]) F(p);
fixed (int* p = a) F(p);
}
}
}

Эдесь показаны несколько использований оператора fixed. Первый оператор фиксирует и получает адрес статического поля, второй оператор фиксирует и получает адрес поля экземпляра, а третий оператор фиксирует и получает адрес элемента массива. В каждом случае было бы ошибкой использовать обычный оператор &, так как эти переменные классифицируются как перемещаемые переменные.

Четвертый оператор fixed в приведенном выше примере дает тот же результат, что и третий.

В этом примере оператора fixed используется тип string:

class Test
{
static string name = "xx";

unsafe static void F(char* p) {
for (int i = 0; p[i]!= '\0'; ++i)
Console.WriteLine(p[i]);
}

static void Main() {
unsafe {
fixed (char* p = name) F(p);
fixed (char* p = "xx") F(p);
}
}
}

В небезопасном контексте элементы массива в одномерном массиве хранятся в порядке возрастания индекса, начиная с индекса 0 и заканчивая индексом Length – 1. В многомерных массивах элементы хранятся так, что сначала возрастают индексы самого правого измерения, затем соседнего левого и так далее влево. В пределах оператора fixed, получающего указатель p на экземпляр массива a, значения указателя в диапазоне от p до p + a.Length - 1 представляют адреса элементов массива. Аналогично переменные в диапазоне от p[0] до p[a.Length - 1] представляют фактические элементы массива. При данном способе хранения массивов можно обращаться с массивом любого измерения как если бы он был линейным.

Пример:

using System;

class Test
{
static void Main() {
int[,,] a = new int[2,3,4];
unsafe {
fixed (int* p = a) {
for (int i = 0; i < a.Length; ++i) // treat as linear
p[i] = i;
}
}

for (int i = 0; i < 2; ++i)
for (int j = 0; j < 3; ++j) {
for (int k = 0; k < 4; ++k)
Console.Write("[{0},{1},{2}] = {3,2} ", i, j, k, a[i,j,k]);
Console.WriteLine();
}
}
}

В результате получается:

[0,0,0] = 0 [0,0,1] = 1 [0,0,2] = 2 [0,0,3] = 3
[0,1,0] = 4 [0,1,1] = 5 [0,1,2] = 6 [0,1,3] = 7
[0,2,0] = 8 [0,2,1] = 9 [0,2,2] = 10 [0,2,3] = 11
[1,0,0] = 12 [1,0,1] = 13 [1,0,2] = 14 [1,0,3] = 15
[1,1,0] = 16 [1,1,1] = 17 [1,1,2] = 18 [1,1,3] = 19
[1,2,0] = 20 [1,2,1] = 21 [1,2,2] = 22 [1,2,3] = 23

В примере

class Test
{
unsafe static void Fill(int* p, int count, int value) {
for (; count!= 0; count--) *p++ = value;
}

static void Main() {
int[] a = new int[100];
unsafe {
fixed (int* p = a) Fill(p, 100, -1);
}
}
}

оператор fixed используется для фиксирования массива, чтобы его адрес передать методу, принимающему указатель.

В примере:

unsafe struct Font
{
public int size;
public fixed char name[32];
}

class Test
{
unsafe static void PutString(string s, char* buffer, int bufSize) {
int len = s.Length;
if (len > bufSize) len = bufSize;
for (int i = 0; i < len; i++) buffer[i] = s[i];
for (int i = len; i < bufSize; i++) buffer[i] = (char)0;
}

Font f;

unsafe static void Main()
{
Test test = new Test();
test.f.size = 10;
fixed (char* p = test.f.name) {
PutString("Times New Roman", p, 32);
}
}
}

оператор fixed используется, чтобы фиксировать буфер фиксированного размера структуры, так чтобы его адрес можно было использовать в качестве указателя.

Значение char*, созданное фиксацией экземпляра строки, всегда указывает на строку, оканчивающуюся символом null. В пределах оператора fixed, получающего указатель p на экземпляр строки s, значения указателя в диапазоне от p до p + s.Length - 1 представляют адреса символов в строке, а значение указателя p + s.Length всегда указывает на символ null (символ со значением '\0').

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

Автоматическое завершение строк символом null особенно удобно при вызове внешних API, ожидающих строки «в стиле C». Отметьте, однако, что в экземпляре строки могут содержаться символы null. Если символы null имеются, то строка будет выглядеть усеченной, если обращаться с ней как с завершающейся символом null строкой char*.

18.7 Буферы фиксированного размера

Буферы фиксированного размера используются для объявления «в стиле C» линейных массивов как членов структур, главным образом они полезны для связи с неуправляемыми API.

18.7.1 Объявления буферов фиксированного размера

Буфер фиксированного размера является членом, представляющим хранилище для буфера фиксированной длины для переменных заданного типа. Объявление буфера фиксированного размера вводит один или более буферов фиксированного размера с заданным типом элементов. Буферы фиксированного размера допускаются только в объявлениях структур и могут быть только в небезопасных контекстах (§18.1).

объявление_члена_структуры:

объявление_буфера_фиксированного_размера

объявление_буфера_фиксированного_размера:
атрибутынеобязательно модификаторы_буфера_фиксированного_размеранеобязательно fixed тип_элемента_буфера
деклараторы_буфера_фиксированного_размера;

модификаторы_буфера_фиксированного_размера:
модификатор_буфера_фиксированного_размера
модификатор_буфера_фиксированного_размера модификаторы_буфера_фиксированного_размера

модификатор_буфера_фиксированного_размера:
new
public
protected
internal
private
unsafe

тип_элемента_буфера:
тип







Дата добавления: 2015-09-07; просмотров: 413. Нарушение авторских прав; Мы поможем в написании вашей работы!



Расчетные и графические задания Равновесный объем - это объем, определяемый равенством спроса и предложения...

Кардиналистский и ординалистский подходы Кардиналистский (количественный подход) к анализу полезности основан на представлении о возможности измерения различных благ в условных единицах полезности...

Обзор компонентов Multisim Компоненты – это основа любой схемы, это все элементы, из которых она состоит. Multisim оперирует с двумя категориями...

Композиция из абстрактных геометрических фигур Данная композиция состоит из линий, штриховки, абстрактных геометрических форм...

Внешняя политика России 1894- 1917 гг. Внешнюю политику Николая II и первый период его царствования определяли, по меньшей мере три важных фактора...

Оценка качества Анализ документации. Имеющийся рецепт, паспорт письменного контроля и номер лекарственной формы соответствуют друг другу. Ингредиенты совместимы, расчеты сделаны верно, паспорт письменного контроля выписан верно. Правильность упаковки и оформления....

БИОХИМИЯ ТКАНЕЙ ЗУБА В составе зуба выделяют минерализованные и неминерализованные ткани...

Ситуация 26. ПРОВЕРЕНО МИНЗДРАВОМ   Станислав Свердлов закончил российско-американский факультет менеджмента Томского государственного университета...

Различия в философии античности, средневековья и Возрождения ♦Венцом античной философии было: Единое Благо, Мировой Ум, Мировая Душа, Космос...

Характерные черты немецкой классической философии 1. Особое понимание роли философии в истории человечества, в развитии мировой культуры. Классические немецкие философы полагали, что философия призвана быть критической совестью культуры, «душой» культуры. 2. Исследовались не только человеческая...

Studopedia.info - Студопедия - 2014-2024 год . (0.011 сек.) русская версия | украинская версия