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

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

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; просмотров: 436. Нарушение авторских прав; Мы поможем в написании вашей работы!




Практические расчеты на срез и смятие При изучении темы обратите внимание на основные расчетные предпосылки и условности расчета...


Функция спроса населения на данный товар Функция спроса населения на данный товар: Qd=7-Р. Функция предложения: Qs= -5+2Р,где...


Аальтернативная стоимость. Кривая производственных возможностей В экономике Буридании есть 100 ед. труда с производительностью 4 м ткани или 2 кг мяса...


Вычисление основной дактилоскопической формулы Вычислением основной дактоформулы обычно занимается следователь. Для этого все десять пальцев разбиваются на пять пар...

Вопрос. Отличие деятельности человека от поведения животных главные отличия деятельности человека от активности животных сводятся к следующему: 1...

Расчет концентрации титрованных растворов с помощью поправочного коэффициента При выполнении серийных анализов ГОСТ или ведомственная инструкция обычно предусматривают применение раствора заданной концентрации или заданного титра...

Психолого-педагогическая характеристика студенческой группы   Характеристика группы составляется по 407 группе очного отделения зооинженерного факультета, бакалавриата по направлению «Биология» РГАУ-МСХА имени К...

ОЧАГОВЫЕ ТЕНИ В ЛЕГКОМ Очаговыми легочными инфильтратами проявляют себя различные по этиологии заболевания, в основе которых лежит бронхо-нодулярный процесс, который при рентгенологическом исследовании дает очагового характера тень, размерами не более 1 см в диаметре...

Примеры решения типовых задач. Пример 1.Степень диссоциации уксусной кислоты в 0,1 М растворе равна 1,32∙10-2   Пример 1.Степень диссоциации уксусной кислоты в 0,1 М растворе равна 1,32∙10-2. Найдите константу диссоциации кислоты и значение рК. Решение. Подставим данные задачи в уравнение закона разбавления К = a2См/(1 –a) =...

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

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