Главная страница
Навигация по странице:

  • Результат выполнения программы (из листинга 4.3) Ⱥɞɪɟɫ start 1830908Ⱥɞɪɟɫ end 1830916Ɋɚɡɧɨɫɬɶ ɚɞɪɟɫɨɜ 8 Глава 4202

  • Указатели на экземпляр структуры

  • Результат выполнения программы (из листинга 4.4)

  • Васильев А.Н. Основы программирования на C#. Васильев А. Н. Программирование


    Скачать 5.54 Mb.
    НазваниеВасильев А. Н. Программирование
    АнкорВасильев А.Н. Основы программирования на C
    Дата20.09.2022
    Размер5.54 Mb.
    Формат файлаpdf
    Имя файлаVasilev_Programmirovanie-na-C-dlya-nachinayushchih-Osobennosti-y.pdf
    ТипДокументы
    #686596
    страница16 из 40
    1   ...   12   13   14   15   16   17   18   19   ...   40
    198
    q
    ПОДРОБНОСТИ bТочнее, значение выражения
    (byte*)pnt+m-1
    вычисляется следующим образом от блока, на который ссылается указатель pnt
    , выполняется m
    смещений с увеличением адреса, а потом
    1
    смещение с уменьшением адреса, и адрес полученного блока возвращается в качестве результата. Можно было воспользоваться командой
    (byte*)pnt+(m-1)
    . В таком случае сразу выполнялось бы m-1
    смещений с увеличением адреса.
    После присваивания нового значения указателю p еще раз выполняется оператор цикла, в котором диапазон изменения индексной переменной k такой же, как ив предыдущем случае. За каждый цикл при заданном значении индекса k отображается значение выражения p[-k]. Особенность данного выражения в том, что индекс отрицательный. Поскольку речь идет об индексировании указателя, то отрицательный индекс означает, что смещение выполняется уменьшением адреса. Другими словами, значение выражения p[-k] — это значение в блоке памяти, который смещен на k позиций (так, что адрес уменьшается) по отношению к блоку памяти, на который ссылается указатель p. Поскольку p ссылается на последний блок области памяти, выделенной для переменной miniarray
    , то проиндексированный отрицательным индексом указатель дает значение соответствующего предыдущего блока. То есть выражение возвращает значение последнего блока, выражение p[-1] возвращает значение предпоследнего блока, выражение p[-2] позволяет узнать значение блока перед предпоследними так далее. В итоге получается, что в консоли отображаются значения, записанные в однобай- товые блоки, но отображаются они в обратном порядке (от последнего блока к начальному).
    Значение целочисленной переменной n вычисляется на основе выражения) как отношение объема памяти, выделяемой для значений (8 байтов, к объему памяти, выделяемой для значений (2 байта. В итоге переменная n получает значение 4. В данном случае мы интерпретируем память, выделенную под переменную miniarray, как 4 последовательно размещенных блока, каждый по 2 байта. Для получения доступа к этим двухбайтовым блокам объявляется указатель q назначение типа char. Значение указателю присваивается командой q=(char*)pnt. Это адрес первого блока в области памяти, выделенной под переменную miniarray. Нов отличие от случая с указателем p, здесь указатель q предназначен

    Указатели
    199
    для работы с символьными значениями. Поэтому базовые блоки, на которые выполняется смещение, двухбайтовые (то есть состоят из двух однобайтовых блоков, а значения в этих двухбайтовых блоках интерпретируются как символьные. Сначала в операторе цикла мы заносим с помощью команды q[k]=(char)(
    ƍAƍ+k) в эти блоки символы, начиная си заканчивая ƍDƍ), и отображаем их в консольном окне. А затем перебрасываем указатель q на последний двухбайтовый блок команда q=(char*)pnt+n-1) и с помощью еще одного оператора цикла, индексируя указатель q отрицательными индексами (выражение q[-k]
    ), отображаем символьные значения двухбайтовых блоков в обратном порядке ПОДРОБНОСТИ bРезультатом выражения
    (char*)pnt+n-1
    является адрес последнего двухбайтового блока в области памяти, выделенной под переменную miniarray
    . Указатель pnt приводится к типу char*
    , поэтому все смещения при выполнении операций адресной арифметики выполняются на уровне блоков размером в 2 байта (такого размера блок выделяется под значение типа char
    ). Значение выражения
    (char*)pnt+n-1
    — это адрес блока, смещенного n-1
    раз (с увеличением адреса) по отношению к блоку, на который ссылается указатель pnt
    . Смещение на одну позицию означает смещение на два однобайтовых блока.
    Еще один пример, в котором иллюстрируются операции с указателями, представлен в листинге 4.3. В каком-то смысле он напоминает предыдущую программу (из листинга 4.2), но реализовано все немного иначе.
    
    Листинг 4.3. Операции с указателями System;
    //
    Ʉɥɚɫɫ ɫ ɝɥɚɜɧɵɦ ɦɟɬɨɞɨɦ:
    class OperationsWithPointersDemo{
    //
    Ƚɥɚɜɧɵɣ ɦɟɬɨɞ:
    unsafe static void Main(){
    //
    Ɉɛɴɹɜɥɟɧɢɟ ɩɟɪɟɦɟɧɧɨɣ ɬɢɩɚ double:
    double val;
    //
    ɐɟɥɨɱɢɫɥɟɧɧɚɹ ɢɧɞɟɤɫɧɚɹ ɩɟɪɟɦɟɧɧɚɹ:
    int k=1;
    Глава 4
    200
    //
    ɍɤɚɡɚɬɟɥɢ ɧɚ ɡɧɚɱɟɧɢɹ ɬɢɩɚ double:
    double* start,end;
    //
    Ɂɧɚɱɟɧɢɹ ɭɤɚɡɚɬɟɥɟɣ:
    start=&val;
    end=start+1;
    //
    Ɉɬɨɛɪɚɠɟɧɢɟ ɚɞɪɟɫɨɜ:
    Console.WriteLine(
    ƎȺɞɪɟɫ start\t{0}Ǝ,(uint)start);
    Console.WriteLine(
    ƎȺɞɪɟɫ end\t{0}Ǝ,(uint)end);
    //
    Ɋɚɡɧɨɫɬɶ ɚɞɪɟɫɨɜ:
    Console.WriteLine(
    ƎɊɚɡɧɨɫɬɶ ɚɞɪɟɫɨɜ {0,6}Ǝ,(uint)end-(uint)start);
    //
    Ɋɚɡɧɨɫɬɶ ɭɤɚɡɚɬɟɥɟɣ:
    Console.WriteLine(
    ƎɊɚɡɧɨɫɬɶ double-ɭɤɚɡɚɬɟɥɟɣ\t{0}Ǝ,end-start);
    Console.WriteLine(
    ƎɊɚɡɧɨɫɬɶ int-ɭɤɚɡɚɬɟɥɟɣ \t{0}Ǝ,(int*)end-(int*)start);
    Console.WriteLine(
    ƎɊɚɡɧɨɫɬɶ char-ɭɤɚɡɚɬɟɥɟɣ\t{0}Ǝ,(char*)end-(char*)start);
    Console.WriteLine(
    ƎɊɚɡɧɨɫɬɶ byte-ɭɤɚɡɚɬɟɥɟɣ\t{0}Ǝ,(byte*)end-(byte*)start);
    //
    ɍɤɚɡɚɬɟɥɶ ɧɚ ɡɧɚɱɟɧɢɟ ɬɢɩɚ byte:
    byte* p=(byte*)start;
    //
    ɍɤɚɡɚɬɟɥɶ ɧɚ ɡɧɚɱɟɧɢɟ ɬɢɩɚ char:
    char* q=(char*)start;
    //
    ɍɤɚɡɚɬɟɥɶ ɧɚ ɡɧɚɱɟɧɢɟ ɬɢɩɚ int:
    int* r=(int*)start;
    Console.WriteLine(
    ƎɌɢɩ byte:Ǝ);
    Console.WriteLine(
    ƎȺɞɪɟɫ\tɁɧɚɱɟɧɢɟƎ);
    //
    Ɂɚɩɨɥɧɟɧɢɟ ɛɥɨɤɨɜ ɩɚɦɹɬɢ ɡɧɚɱɟɧɢɹɦɢ ɢ ɨɬɨɛɪɚɠɟɧɢɟ
    //
    ɡɧɚɱɟɧɢɣ ɢɡ ɛɥɨɤɨɜ ɩɚɦɹɬɢ:
    while(p //
    Ɂɧɚɱɟɧɢɟ ɡɚɩɢɫɵɜɚɟɬɫɹ ɜ ɛɥɨɤ ɩɚɦɹɬɢ:
    *p=(byte)k;
    //
    Ɉɬɨɛɪɚɠɟɧɢɟ ɚɞɪɟɫɚ ɢ ɡɧɚɱɟɧɢɹ ɢɡ ɛɥɨɤɚ ɩɚɦɹɬɢ:
    Console.WriteLine(
    Ǝ{0}\t{1}Ǝ,(uint)p,*p);
    //
    ɍɜɟɥɢɱɟɧɢɟ ɡɧɚɱɟɧɢɹ ɭɤɚɡɚɬɟɥɹ:
    p++;
    Указатели //
    ɇɨɜɨɟ ɡɧɚɱɟɧɢɟ ɩɟɪɟɦɟɧɧɨɣ:
    k+=2;
    }
    Console.WriteLine(
    ƎɌɢɩ char:Ǝ);
    Console.WriteLine(
    ƎȺɞɪɟɫ\tɁɧɚɱɟɧɢɟƎ);
    //
    Ɂɚɩɨɥɧɟɧɢɟ ɛɥɨɤɨɜ ɩɚɦɹɬɢ ɡɧɚɱɟɧɢɹɦɢ ɢ ɨɬɨɛɪɚɠɟɧɢɟ
    //
    ɡɧɚɱɟɧɢɣ ɢɡ ɛɥɨɤɨɜ ɩɚɦɹɬɢ:
    for(k=0;q+k //
    Ɂɧɚɱɟɧɢɟ ɡɚɩɢɫɵɜɚɟɬɫɹ ɜ ɛɥɨɤ ɩɚɦɹɬɢ:
    *(q+k)=(char)(
    ƍAƍ+2*k);
    //
    Ɉɬɨɛɪɚɠɟɧɢɟ ɚɞɪɟɫɚ ɢ ɡɧɚɱɟɧɢɹ ɢɡ ɛɥɨɤɚ ɩɚɦɹɬɢ:
    Console.WriteLine(
    Ǝ{0}\t{1}Ǝ,(uint)(q+k),*(q+k));
    }
    Console.WriteLine(
    ƎɌɢɩ int:Ǝ);
    Console.WriteLine(
    ƎȺɞɪɟɫ\tɁɧɚɱɟɧɢɟƎ);
    //
    Ɂɚɩɨɥɧɟɧɢɟ ɛɥɨɤɨɜ ɩɚɦɹɬɢ ɡɧɚɱɟɧɢɹɦɢ ɢ ɨɬɨɛɪɚɠɟɧɢɟ
    //
    ɡɧɚɱɟɧɢɣ ɢɡ ɛɥɨɤɨɜ ɩɚɦɹɬɢ:
    for(k=0;&r[k] //
    Ɂɧɚɱɟɧɢɟ ɡɚɩɢɫɵɜɚɟɬɫɹ ɜ ɛɥɨɤ ɩɚɦɹɬɢ:
    r[k]=5*(k+1);
    //
    Ɉɬɨɛɪɚɠɟɧɢɟ ɚɞɪɟɫɚ ɢ ɡɧɚɱɟɧɢɹ ɢɡ ɛɥɨɤɚ ɩɚɦɹɬɢ:
    Console.WriteLine(
    Ǝ{0}\t{1}Ǝ,(uint)&r[k],r[k]);
    }
    Результат выполнения программы может быть таким, как показано ниже:
    
    Результат выполнения программы (из листинга 4.3)
    Ⱥɞɪɟɫ start 1830908
    Ⱥɞɪɟɫ end 1830916
    Ɋɚɡɧɨɫɬɶ ɚɞɪɟɫɨɜ 8
    Глава 4
    202
    Ɋɚɡɧɨɫɬɶ double-ɭɤɚɡɚɬɟɥɟɣ 1
    Ɋɚɡɧɨɫɬɶ int-ɭɤɚɡɚɬɟɥɟɣ 2
    Ɋɚɡɧɨɫɬɶ char-ɭɤɚɡɚɬɟɥɟɣ 4
    Ɋɚɡɧɨɫɬɶ byte-ɭɤɚɡɚɬɟɥɟɣ 8
    Ɍɢɩ byte:
    Ⱥɞɪɟɫ Ɂɧɚɱɟɧɢɟ
    1830908 1 1830909 3 1830910 5 1830911 7 1830912 9 1830913 11 1830914 13 1830915 15
    Ɍɢɩ char:
    Ⱥɞɪɟɫ Ɂɧɚɱɟɧɢɟ
    1830908 A
    1830910 C
    1830912 E
    1830914 G
    Ɍɢɩ int:
    Ⱥɞɪɟɫ Ɂɧɚɱɟɧɢɟ
    1830908 5 1830912 В этой программе мы объявляем переменную val типа double, атак- же указатели start и end, предназначенные для работы со значениями типа double. Командой start=&val указатель start получает в качестве значения адрес переменной val. Значение указателю end присваивается командой end=start+1, в результате чего в указатель end записывается адрес блока, расположенного сразу за областью памяти, выделенной под переменную val.
    Указатели ПОДРОБНОСТИ bОбласть памяти, выделенная под переменную val
    , состоит из 8 од- нобайтовых блоков. В указатель start записывается адрес первого из этих 8 блоков. При прибавлении числа
    1
    к указателю в команде end=start+1
    ) выполняется смещение на один блок размера, равного объему памяти, выделяемой под значение
    (8 байтов. В результате в указатель end записывается адрес блока, расположенного за 8 однобайтовыми блоками, выделенными под переменную Значения адресов, которые вычисляются выражениями (uint)start и (uint)end, отображаются в консольном окне. В принципе, сами адреса от запуска к запуску меняются. Но разница между значениями адресов (вычисляется как разность (uint)end-(uint)start) всегда одна и та же и равна 8. Причина в том, что адрес приписывается каждому одно- байтовому блоку. Адреса соседних однобайтовых блоков отличаются на 1. Под значение типа double выделяется 8 однобайтовых блоков, отсюда и результат. Но вот если мы вычислим разность указателей end-start, то получим значение 1. Указатели end и start объявлены для работы с значениями. Разность этих указателей — это количество значений типа double, которые можно записать между соответствующими адресами. В данном случае между адресами (с учетом начального блока, на который ссылается указатель start) находится 8 однобайтовых значений. В эту область можно записать одно значение типа При вычислении выражения (int*)end-(int*)start мы получаем значение 2. Здесь, как и при вычислении выражения end-start, вычисляется разность указателей. Но эти указатели предварительно приведены к типу int*. То есть мы имеем дело с указателями, предназначенными для работы с целочисленными значениями типа int. Поэтому значением выражения (int*)end-(int*)start является целое число, равное количеству ячеек для значений типа int, которые помещаются в области памяти между адресами из указателей end и start. Как мы уже знаем, там 8 однобайтовых ячеек, а для записи значения типа int нужно 4 байта. Получается, что в данную область памяти можно записать два значения типа Аналогично при вычислении выражения (char*)end-(char*)
    start в результате получаем число 4. Это количество блоков,
    Глава которые помещаются в области памяти, выделенной под переменную. Ну и несложно догадаться, почему результатом выражения
    (byte*)end-(byte*)start является число Командами byte* p=(byte*)start, char* q=(char*)start и int* r=(int*)start объявляются указатели p, q и r назначения типа byte, char и int соответственно. В каждый из указателей копируется адрес, записанный в указатель start. Поскольку указатели разного типа, то используется явное приведение типов. Далее действуем такс помощью каждого из указателей заполняем значениями область памяти, выделенную под переменную val, и отображаем эти значения в консольном окне. Технология решения задачи каждый раз разная.
    Для заполнения области памяти значениями запускаем оператор цикла while, в котором проверяется условие pk в однобайтовую ячейку, на которую ссылается указатель p, записывается значение целочисленной переменной k (начальное значение 1), а затем отображается адрес ячейки (инструкция (uint)p) и значение в этой ячейке (инструкция *p). Командой p++ увеличивается значение указателя (в результате указатель будет указывать на соседнюю ячейку, а командой k+=2 текущее значение переменной k увеличивается на В следующем операторе цикла for переменная k принимает начальное значение 0. За каждый цикл значение переменной k увеличивается на 1. Оператор выполняется, пока истинно условие q+kƍAƍ+2*k) в блок памяти, на который ссылается указатель q+k, записывается символьное значение, которое получается прибавлением к коду символа
    ƍAƍ значения
    2*k с последующим преобразованием к типу char (получаем буквы через одну, начиная с буквы
    ƍAƍ). Также отображается адрес блока (инструкция
    (uint)(q+k)
    ) и значение в этом блоке (инструкция В еще одном операторе цикла for проверяется условие &r[k]

    Указатели
    205
    int
    -значения. Выражение &r[k] — это адрес блока, в который записано значение r[k]. Этот адрес должен быть меньше адреса из указателя В телеоператора цикла командой r[k]=5*(k+1) в соответствующий блок записывается значение (числа 5 и 10, а больше не помещается. Адрес блока (инструкция (uint)&r[k]) и значение из блока (инструкция r[k]
    ) отображаются в консольном окне НАЗ А МЕТКУ При отображении адресов, если используется указатель назначение типа byte
    , дискретность изменения адреса равна
    1
    . При отображении адресов с помощью указателей назначения типа char дискретность изменения адреса равна
    2
    . При использовании указателя назначение типа int дискретность изменения адреса равна Фактически дискретность изменения адреса определяется количеством однобайтовых блоков, используемых для записи значения соответствующего типа.
    Указатели на экземпляр структуры
    Тогда помните для вас законы не писаны. Действуйте только по моим инструкциям.
    из м/ф Приключения капитана Врунгеля»
    Если структура не содержит членов ссылочного типа, то для экземпляра такой структуры можно создать указатель. При объявлении указателя на экземпляр структуры тип указателя описывают как имя структуры, после которого стоит звездочка *. Например, если имеется структура
    MyStruct
    (без членов ссылочного типа) и мы хотим объявить указатель pnt на экземпляр такой структуры, то объявление указателя может выглядеть следующим образом Указателю на экземпляр структуры в качестве значения присваивается адрес экземпляра структуры. Адрес экземпляра можно получить, разместив перед именем экземпляра инструкцию &. Чтобы по указателю получить доступ к экземпляру структуры, можем перед указателем поставить звездочку *. Но поскольку в экземпляре структуры нас обычно
    Глава интересуют поля и методы, удобнее воспользоваться оператором -> стрелка. Он используется в формате
    ɭɤɚɡɚɬɟɥɶ->ɩɨɥɟ или ɭɤɚɡɚ-
    ɬɟɥɶ->ɦɟɬɨɞ(ɚɪɝɭɦɟɧɬɵ). Небольшой пример, в котором использованы указатели на структуры, представлен в листинге Листинг 4.4. Указатели на экземпляр структуры System;
    //
    Ɉɩɢɫɚɧɢɟ ɫɬɪɭɤɬɭɪɵ:
    struct MyStruct{
    //
    ɉɨɥɟ:
    public int code;
    //
    Ɇɟɬɨɞ:
    public void show(){
    //
    Ɉɬɨɛɪɚɠɟɧɢɟ ɡɧɚɱɟɧɢɹ ɩɨɥɹ:
    Console.WriteLine(
    Ǝɉɨɥɟ code: Ǝ+code);
    }
    }
    //
    Ʉɥɚɫɫ ɫ ɝɥɚɜɧɵɦ ɦɟɬɨɞɨɦ:
    class StructsAndPointersDemo{
    //
    Ƚɥɚɜɧɵɣ ɦɟɬɨɞ:
    unsafe static void Main(){
    //
    ɋɨɡɞɚɸɬɫɹ ɷɤɡɟɦɩɥɹɪɵ ɫɬɪɭɤɬɭɪɵ:
    MyStruct A,B;
    //
    Ɉɛɴɹɜɥɹɟɬɫɹ ɭɤɚɡɚɬɟɥɶ ɧɚ ɷɤɡɟɦɩɥɹɪ ɫɬɪɭɤɬɭɪɵ:
    MyStruct* p;
    //
    ɍɤɚɡɚɬɟɥɸ ɩɪɢɫɜɚɢɜɚɟɬɫɹ ɡɧɚɱɟɧɢɟ:
    p=&A;
    //
    Ɉɛɪɚɳɟɧɢɟ ɤ ɩɨɥɸ ɱɟɪɟɡ ɭɤɚɡɚɬɟɥɶ:
    p->code=123;
    //
    ȼɵɡɨɜ ɦɟɬɨɞɚ ɱɟɪɟɡ ɭɤɚɡɚɬɟɥɶ:
    p->show();
    //
    ȼɵɡɨɜ ɦɟɬɨɞɚ ɱɟɪɟɡ ɷɤɡɟɦɩɥɹɪ ɫɬɪɭɤɬɭɪɵ:
    A.show();
    Указатели Console.WriteLine(
    Ǝ--------------Ǝ);
    //
    ɇɨɜɨɟ ɡɧɚɱɟɧɢɟ ɭɤɚɡɚɬɟɥɹ:
    p=&B;
    //
    Ɉɛɪɚɳɟɧɢɟ ɤ ɩɨɥɸ ɱɟɪɟɡ ɭɤɚɡɚɬɟɥɶ:
    p->code=321;
    //
    ȼɵɡɨɜ ɦɟɬɨɞɚ ɱɟɪɟɡ ɭɤɚɡɚɬɟɥɶ:
    p->show();
    //
    ȼɵɡɨɜ ɦɟɬɨɞɚ ɱɟɪɟɡ ɷɤɡɟɦɩɥɹɪ ɫɬɪɭɤɬɭɪɵ:
    B.show();
    Console.WriteLine(
    Ǝ--------------Ǝ);
    //
    ȿɳɟ ɨɞɢɧ ɫɩɨɫɨɛ ɨɛɪɚɬɢɬɶɫɹ ɤ ɩɨɥɸ:
    (*p).code=456;
    //
    ȿɳɟ ɨɞɢɧ ɫɩɨɫɨɛ ɜɵɡɜɚɬɶ ɦɟɬɨɞ:
    (*p).show();
    //
    ȼɵɡɨɜ ɦɟɬɨɞɚ ɱɟɪɟɡ ɷɤɡɟɦɩɥɹɪ ɫɬɪɭɤɬɭɪɵ:
    B.show();
    Результат выполнения программы следующий:
    
    Результат выполнения программы (из листинга 4.4)
    ɉɨɥɟ code: 123
    ɉɨɥɟ code: 123
    --------------
    ɉɨɥɟ code: 321
    ɉɨɥɟ code: 321
    --------------
    ɉɨɥɟ code: 456
    ɉɨɥɟ code: В программе описана структура MyStruct, в которой есть открытое целочисленное поле code и открытый метод show(). Метод при вызове
    Глава отображает в консольном окне значение поля code экземпляра структуры, из которого вызывается.
    В главном методе программы командой MyStruct A,B создаются экземпляры и B структуры MyStruct. Командой MyStruct* p объявляется указатель p на экземпляр структуры MyStruct. Значение указателю присваивается командой p=&A. После ее выполнения указатель p ссылается на экземпляр A. Поэтому инструкция p->code является ссылкой на поле code экземпляра A. Например, командой p->code=123 полю code экземпляра A присваивается значение 123. Командой p->show() из экземпляра A вызывается метод show(). Для проверки этот же метод вызывается командой A.show(). Результаты обоих вызовов совпадают, как и должно быть.
    После выполнения команды p=&B указатель p ссылается на экземпляр B. Поэтому при выполнении команды p->code=321 значение присваивается полю code экземпляра B. Соответственно, результат выполнения команды p->show() такой же, как и команды B.show(), поскольку в обоих случаях вызывается метод show() экземпляра Стоит также заметить, что доступ к экземпляру можно получить с помощью инструкции *p. Например, при выполнении инструкции (*p).
    code=456
    (круглые скобки нужны для изменения порядка применения операторов) присваивается значение полю code экземпляра B. Метод show()
    из этого экземпляра можно вызвать с помощью инструкции Инструкция  Форму будете создавать под моим личным контролем.
    из к/ф «Чародеи»
    Представим себе такую ситуацию. В программе создан объект класса, и у этого объекта есть поле (например, целочисленное. Мы не можем создать указатель для объекта, но можем создать указатель для поля, поскольку фактически это некоторая переменная. Но при этом мы сталкиваемся с потенциальной проблемой. Дело в том, что если в какой-то момент окажется, что в программе ссылок на объект больше нет (а это вполне реальная ситуация, то объект из памяти может быть удален. И тогда указатель будет

    Указатели
    209
    ссылаться на область памяти, которая больше не используется для хранения значения поля. Такие ситуации считаются (и являются) потенциально опасными. Они блокируются просто так указатель на поле объекта не создать, приходится использовать специальный подход НАЗ А МЕТКУ То, что на поле объекта ссылается указатель, само по себе не защищает объект от удаления. В расчет принимаются только объектные переменные, которые ссылаются на объект. Если таких ссылок нет, объект помещается в очередь на удаление.
    Для предотвращения удаления (системой сборки мусора) переменных например, поля объекта, на которые ссылаются указатели, используется инструкция fixed. Шаблон использования этой инструкции представлен ниже (жирным шрифтом выделены ключевые элементы шаблона ɭɤɚɡɚɬɟɥɶ=&ɩɟɪɟɦɟɧɧɚɹ
    1   ...   12   13   14   15   16   17   18   19   ...   40


    написать администратору сайта