다음을 통해 공유


포인터 형식(C# 프로그래밍 가이드)

안전하지 않은 컨텍스트에서는 형식이 포인터 형식, 값 형식 또는 참조 형식이 될 수 있습니다. 포인터 형식 선언은 다음 형식 중 하나를 사용합니다.

type* identifier;
void* identifier; //allowed but not recommended

포인터 형식은 다음과 같은 형식일 수 있습니다.

포인터 형식은 개체에서 상속되지 않으며 포인터 형식과 object는 서로 변환되지 않습니다. 또한 boxing과 unboxing은 포인터를 지원하지 않습니다. 그러나 다른 포인터 형식 간의 변환 및 포인터 형식과 정수 계열 형식 사이의 변환은 허용됩니다.

동일한 선언에서 여러 포인터를 선언하는 경우 별표(*)는 기본 형식에만 함께 사용되고 각 포인터 이름의 접두사로는 사용되지 않습니다. 예를 들면 다음과 같습니다.

int* p1, p2, p3;   // Ok
int *p1, *p2, *p3;   // Invalid in C#

개체 참조는 포인터가 해당 개체 참조를 가리키는 경우에도 가비지 수집될 수 있으므로 포인터는 참조나 참조가 들어 있는 구조체를 가리킬 수 없습니다. 가비지 수집기는 포인터 형식에서 개체를 가리키는지 여부를 추적하지 않습니다.

myType* 형식의 포인터 변수 값은 myType 형식의 변수 주소입니다. 다음은 포인터 형식 선언의 예제입니다.

예제

설명

int* p

p는 정수에 대한 포인터입니다.

int** p

p는 정수에 대한 포인터를 가리키는 포인터입니다.

int*[] p

p는 정수에 대한 포인터의 1차원 배열입니다.

char* p

p는 문자에 대한 포인터입니다.

void* p

p는 알 수 없는 형식에 대한 포인터입니다.

포인터 간접 참조 연산자 *를 사용하면 포인터 변수가 가리키는 위치의 내용에 액세스할 수 있습니다. 예를 들어, 다음 선언을 참조하십시오.

int* myVariable;

여기서 *myVariable 식은 myVariable에 포함된 주소에 있는 int 변수를 가리킵니다.

fixed 문(C# 참조)포인터 변환(C# 프로그래밍 가이드) 항목에 포인터에 대한 몇 가지 예제가 나와 있습니다. 다음 예제는 unsafe 키워드 및 fixed 문에 대한 필요성과 정수 포인터를 증분하는 방법을 보여줍니다. 이 코드를 실행하려면 콘솔 응용 프로그램의 주 함수에 붙여 넣습니다. (프로젝트 디자이너에서 안전하지 않은 코드를 사용하도록 설정하십시오. 메뉴 모음에서 프로젝트, 속성을 선택한 다음 빌드 탭에서 안전하지 않은 코드 허용을 선택합니다.)

// Normal pointer to an object.
int[] a = new int[5] {10, 20, 30, 40, 50};
// Must be in unsafe code to use interior pointers.
unsafe
{
    // Must pin object on heap so that it doesn't move while using interior pointers.
    fixed (int* p = &a[0])
    {
        // p is pinned as well as object, so create another pointer to show incrementing it.
        int* p2 = p;
        Console.WriteLine(*p2);
        // Incrementing p2 bumps the pointer by four bytes due to its type ...
        p2 += 1;
        Console.WriteLine(*p2);
        p2 += 1;
        Console.WriteLine(*p2);
        Console.WriteLine("--------");
        Console.WriteLine(*p);
        // Deferencing p and incrementing changes the value of a[0] ...
        *p += 1;
        Console.WriteLine(*p);
        *p += 1;
        Console.WriteLine(*p);
    }
}

Console.WriteLine("--------");
Console.WriteLine(a[0]);
Console.ReadLine();

// Output:
//10
//20
//30
//--------
//10
//11
//12
//--------
//12

void* 형식의 포인터에는 간접 참조 연산자를 적용할 수 없습니다. 그러나 캐스트를 사용하여 void 포인터를 다른 포인터 형식으로 변환하거나 반대로 변환할 수 있습니다.

포인터는 null일 수 있습니다. null 포인터에 간접 참조 연산자를 적용할 때 발생하는 동작은 구현에 따라 다릅니다.

메서드 사이에 포인터를 전달하면 정의되지 않은 동작이 발생할 수 있다는 사실에 주의해야 합니다. Out 또는 Ref 매개 변수를 통해, 또는 함수 결과로 지역 변수에 포인터를 반환하는 경우를 예로 들 수 있습니다. fixed 블록에서 포인터가 설정되면 이 포인터가 가리키는 변수의 고정 상태가 해제될 수 있습니다.

다음 표에서는 안전하지 않은 컨텍스트에서 포인터에 대해 수행할 수 있는 연산자와 문을 보여 줍니다.

연산자/문

기능

*

포인터 간접 참조를 수행합니다.

->

포인터를 통해 구조체 멤버에 액세스합니다.

[]

포인터를 인덱싱합니다.

&

변수 주소를 가져옵니다.

++ 및 --

포인터를 증가 및 감소시킵니다.

+ 및 -

포인터 연산을 수행합니다.

==, !=, <, >, <=, >=

포인터를 비교합니다.

stackalloc

스택에 메모리를 할당합니다.

fixed 문

해당 주소를 찾을 수 있도록 임시로 변수를 고정합니다.

C# 언어 사양

자세한 내용은 C# 언어 사양을 참조하세요. C# 언어 사양은 C# 구문 및 사용법에 대한 신뢰할 수 있는 소스입니다.

참고 항목

참조

안전하지 않은 코드 및 포인터(C# 프로그래밍 가이드)

포인터 변환(C# 프로그래밍 가이드)

포인터 식(C# 프로그래밍 가이드)

unsafe(C# 참조)

fixed 문(C# 참조)

stackalloc(C# 참조)

Boxing 및 Unboxing(C# 프로그래밍 가이드)

개념

C# 프로그래밍 가이드

기타 리소스

형식(C# 참조)