English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

C# базовый учебник

C# продвинутый учебник

C# направленный на объект (OOP)

Несafe код в C#

Когда блок кода использует unsafe Модификатор mark при использовании в функции переменных указателей позволяет в C#.небезопасный кодили нескоординированный код - это код, который используетУказательБлок кода переменной.

Переменная указателя

Указатель Это переменная, значение которой адрес другого переменного, то есть прямая адреса памяти. Как и другие переменные или константы, вам необходимо declarations указателя перед использованием переменного указателя для хранения адреса другой переменной.

Общий вид declarations переменных указателей:

type* var-name;

Ниже приведены примеры declarations типа указателей:

ПримерОписание
int* pp - это указатель на целое число.
double* pp - это указатель на двойную точку.
float* pp - это указатель на плавающую точку.
int** pp - это указатель на указатель на целое число.
int*[] pp - это одномерный массив указателей на целое число.
char* pp - это указатель на символ.
void* pp - это указатель на неизвестный тип.

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

int* p1, p2, p3; // правильно  
int* p1, *p2, *p3; // ошибка

Пример показывает использование в C#: unsafe Использование указателей в модификаторах:

using System;
namespace UnsafeCodeApplication
{
    class Program
    {
        static unsafe void Main(string[] args)
        {
            int var = 20;
            int* p = &var;
            Console.WriteLine("Данные: {0}", var);
            Console.WriteLine("Адрес: {0}", (int)p);
            Console.ReadKey();
        }
    }
}

Когда上面的 код компилируется и выполняется, он会产生下列结果:

Данные: 20
Адрес: 99215364

Вы также можете не声明 весь метод в качестве не安全的 кода, достаточно声明 часть метода как не безопасный. Пример показывает это.

Использование указателей для получения значений данных

Вы можете использовать ToString() Метод ищет данные, хранящиеся в指针ной переменной. Пример демонстрирует это:

using System;
namespace UnsafeCodeApplication
{
   class Program
   {
      public static void Main()
      {
         unsafe
         {
            int var = 20;
            int* p = &var;
            Console.WriteLine("Данные: {0}", var);
            Console.WriteLine("Данные: {0}", p->ToString());
            Console.WriteLine("Адрес: {0}", (int)p);
         }
         Console.ReadKey();
      }
   }
}

Когда上面的 код компилируется и выполняется, он会产生下列结果:

Данные: 20
Данные: 20
Адрес: 77128984

Передача указателя в качестве аргумента метода

Вы можете передать переменную указателя в качестве аргумента метода. Пример показывает это:

using System;
namespace UnsafeCodeApplication
{
   class TestPointer
   {
      public unsafe void swap(int* p, int* q)
      {
         int temp = *p;
         *p = *q;
         *q = temp;
      }
      public unsafe static void Main()
      {
         TestPointer p = new TestPointer();
         int var1 = 10;
         int var2 = 20;
         int* x = &var1;
         int* y = &var2;
         
         Console.WriteLine("Before Swap: var1: {0}, var2: {1}", var1, var2);
         p.swap(x, y);
         Console.WriteLine("После обмена: var1:{0}, var2: {1}", var1, var2);
         Console.ReadKey();
      }
   }
}

Когда上面的 код компилируется и выполняется, он会产生下列结果:

До обмена: var1: 10, var2: 20
После обмена: var1: 20, var2: 10

Доступ к элементам массива с помощью указателя

В C#, имя массива и указатель на данные массива, имеющие тот же тип данных, являются различными типами переменных. Например, int *p и int[] p — это разные типы. Вы можете увеличить переменную указателя p, так как она не фиксирована в памяти, но адрес массива фиксирован в памяти, поэтому вы не можете увеличить массив p.

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

Ниже приведен пример, демонстрирующий это:

using System;
namespace UnsafeCodeApplication
{
   class TestPointer
   {
      public unsafe static void Main()
      {
         int[] list = {10, 100, 200};
         fixed(int *ptr = list)
         /* Отображение адресов массивов в указателе */
         for (int i = 0; i < 3; i++)
         {
            Console.WriteLine("Адрес list[{0}]={1}", i, (int)(ptr + i));
            Console.WriteLine("Значение list[{0}]={1}", i, *(ptr + i));
         }
         Console.ReadKey();
      }
   }
}

Когда上面的 код компилируется и выполняется, он会产生下列结果:

Адрес list[0] = 31627168
Значение list[0] = 10
Адрес list[1] = 31627172
Значение list[1] = 100
Адрес list[2] = 31627176
Значение list[2] = 200

Компиляция несанкционированного кода

Чтобы компилировать несанкционированный код, вам необходимо переключиться на компилятор командной строки. /unsafe Командная строка.

Например, чтобы скомпилировать программу, содержащую несafe код,命名为 prog1.cs, введите команду в командной строке:

csc /unsafe prog1.cs

Если вы используете Visual Studio IDE, вам нужно включить несafe код в свойствах проекта.

Шаги следующие:

  • Откройте, дважды щелкнув по узлу свойств (properties) в ресурсном управлении (Solution Explorer)Свойства проекта (Project properties)

  • Нажмите Собрать Вкладка.

  • Выберите опцию"Разрешить несafe код"。