English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
当一个代码块使用 unsafe 修饰符标记时,C# 允许在函数中使用指针变量。不安全代码或非托管代码是指使用了指针变量的代码块。
指针 是值为另一个变量的地址的变量,即,内存位置的直接地址。就像其他变量或常量,您必须在使用指针存储其他变量地址之前声明指针。
指针变量声明的一般形式为:
type* var-name;
下面是指针类型声明的示例:
예제 | 描述 |
---|---|
int* p | p 是指向整数的指针。 |
double* p | p 是指向双精度数的指针。 |
float* p | p 是指向浮点数的指针。 |
int** p | p 是指向整数的指针的指针。 |
int*[] p | p 是指向整数的指针的一维数组。 |
char* p | p 是指向字符的指针。 |
void* p | p 是指向未知类型的指针。 |
在同一个声明中声明多个指针时,星号 * 仅与基础类型一起写入;而不是用作每个指针名称的前缀。 例如:
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("Data is: {0} ", var); Console.WriteLine("Address is: {0}", (int)p); Console.ReadKey(); } } }
위의 코드가 컴파일되고 실행될 때, 다음과 같은 결과가 생성됩니다:
Data is: 20 Address is: 99215364
您也可以不声明整个方法作为不安全代码,只需声明方法的一部分作为不安全代码。下面的示例说明了这一点。
您可以使用 ToString() 方法检索存储在指针变量所引用位置的数据。下面的示例演示了这一点:
using System; namespace UnsafeCodeApplication { class Program { public static void Main() { unsafe { int var = 20; int* p = &var; Console.WriteLine("Data is: {0} ", var); Console.WriteLine("Data is: {0} ", p->ToString()); Console.WriteLine("Address is: {0} ", (int)p); } Console.ReadKey(); } } }
위의 코드가 컴파일되고 실행될 때, 다음과 같은 결과가 생성됩니다:
Data is: 20 Data is: 20 Address is: 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}1, var2); p.swap(x, y); Console.WriteLine("After Swap: var1:{0}, var2: {1}1, var2); Console.ReadKey(); } } }
위의 코드가 컴파일되고 실행될 때, 다음과 같은 결과가 생성됩니다:
Before Swap: var1: 10, var2: 20 After Swap: var1: 20, var2: 10
C#에서, 배열 이름과 배열 데이터와 같은 데이터 타입을 가진 포인터는 다른 변수 타입입니다. 예를 들어, int *p와 int[] p는 다른 타입입니다. p 포인터 변수는 메모리에서 고정되어 있지 않기 때문에 증가할 수 있습니다. 그러나 배열 주소는 메모리에서 고정되어 있기 때문에 배열 p를 증가시킬 수 없습니다.
따라서, 포인터 변수 p를 사용하여 배열 데이터에 접근하려면, C#에서 배열 이름과 배열 데이터와 같은 데이터 타입을 가진 포인터는 다른 변수 타입입니다. 예를 들어, int++ 그러므로, 포인터 변수를 사용하여 배열 데이터에 접근할 필요가 있으면, 우리가 일반적으로 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)); Console.WriteLine("list[{0}]의 값={1} *(ptr + i)); } Console.ReadKey(); } } }
위의 코드가 컴파일되고 실행될 때, 다음과 같은 결과가 생성됩니다:
list[0]의 주소 = 31627168 list[0]의 값 = 10 list[의 주소1] = 31627172 list[의 값1] = 100 list[의 주소2] = 31627176 list[의 값2] = 200
비안전한 코드를 컴파일하려면 명령 프롬프트 컴파일러로 전환해야 합니다. /unsafe 명령 프롬프트.
예를 들어, 불안전 코드를 포함한 이름이 prog인 프로그램을 컴파일하려면1.cs 프로그램을 컴파일하려면 명령 줄에서 다음 명령어를 입력하십시오:
csc /unsafe prog1.cs
Visual Studio IDE를 사용하는 경우, 프로젝트 속성에서 불안전 코드를 활성화해야 합니다。
하단 단계와 같이 합니다:
자원 관리자(Solution Explorer)에서 속성 노드를 더블 클릭하여 열기프로젝트 속성(프로젝트 속성)。
클릭 빌드 탭
선택 옵션"불안전 코드 허용"。