문제

방금 C#에서 스왑 루틴을 만들었습니다.

static void Swap(ref int x, ref int y)
{
    int temp = x;
    x = y;
    y = temp;
}

이 C ++ 코드와 같은 작업을 수행합니다.

void swap(int *d1, int *d2)
{
    int temp=*d1;
    *d1=*d2;
    *d2=temp;
}

그렇습니다 ref 그리고 out 사용하지 않고 C#의 포인터와 같은 키워드 unsafe 암호?

도움이 되었습니까?

해결책

그들은 더 제한적입니다. 포인터에서 ++를 말할 수는 있지만 ref 또는 out.


편집하다 의견에 약간의 혼란이 있으므로 절대적으로 명확하게 말합니다. 여기서 요점은 포인터의 기능과 비교하는 것입니다. 동일한 작업을 수행 할 수 없습니다 ptr++ a ref/out, 즉, 메모리의 인접한 위치를 다루게합니다. 당신이 동등한 것을 수행 할 수 있다는 것은 사실입니다 (그러나 여기서는 관련이 없습니다) (*ptr)++, 그러나 그것은 그것을 다음의 기능과 비교하는 것입니다. 가치, 포인터가 아닙니다.


스택이 움직이지 않고 C#이 신중하게 구성되어있어 ref 그리고 out 항상 스택의 활성 영역을 참조하십시오.


편집하다 절대적으로 분명하게 (아래의 예에서 아직 명확하지 않은 경우) 여기 요점은 그렇지 않습니다. ref/out ~할 수 있다 스택을 가리 킵니다. 그게 다야 언제 그것은 스택을 가리키며, 언어 규칙이 매달려있는 포인터가되지 않도록 보장됩니다. 스택은 메소드 콜 종료에 따라 정보를 폐기하기 때문에이 보증은 필요합니다 (및 관련/흥미로운).

반대로 ref/out GC 힙의 객체를 말하면 해당 객체가 필요한만큼 오래 살아남을 수 있다는 것은 놀라운 일이 아닙니다. GC 힙은 추천자가 요구하는 시간 동안 객체를 유지하기 위해 정확하게 설계되었으며 (고정기) Pinning을 제공합니다. GC 압축으로 객체를 이동해서는 안되는 상황을 지원하려면 아래 예제)을 참조하십시오.


안전하지 않은 코드로 Interop을 사용하면 ref 포인터와 매우 밀접한 관련이 있습니다. 예를 들어, COM 인터페이스가 다음과 같이 선언 된 경우 :

HRESULT Write(BYTE *pBuffer, UINT size);

인터 로프 어셈블리는 다음과 같이 전환합니다.

void Write(ref byte pBuffer, uint size);

그리고 당신은 이것을 호출하기 위해 이것을 할 수 있습니다 (COM Interop 물건이 배열 고정을 처리한다고 생각합니다).

byte[] b = new byte[1000];
obj.Write(ref b[0], b.Length);

다시 말해, ref 첫 번째 바이트는 모든 것에 액세스 할 수있게 해줍니다. 그것은 분명히 첫 바이트에 대한 포인터입니다.

다른 팁

C#의 참조 매개 변수는 대체하는 데 사용될 수 있습니다. 하나 포인터 사용, 예. 그러나 전부는 아닙니다.

포인터에 대한 또 다른 일반적인 용도는 배열을 반복하는 수단입니다. out/ref 매개 변수는 그렇게 할 수 없으므로 "포인터와 동일하지 않습니다".

ref 그리고 out 인수가 값 대신 참조로 전달되어야 함을 나타내는 기능 인수와 함께 사용됩니다. 이런 의미에서 예, 그들은 C ++의 포인터와 다소 비슷합니다 (실제로 참조와 마찬가지로). 그것에 대해 자세히 알아보십시오 이 기사.

실제로, 나는 그것들을 포인터보다는 C ++ 참조와 비교할 것입니다. C ++ 및 C의 포인터는보다 일반적인 개념이며, 참조는 원하는대로 할 것입니다.

물론 이들 모두는 의심 할 여지없이 덮개 아래의 포인터입니다.

사용에 대한 좋은 점 밖으로 항목에 값이 할당되도록 보장됩니다. 그렇지 않은 경우 컴파일 오류가 발생합니다.

비교가 보는 사람의 눈에있는 동안 ... 나는 아니오라고 말합니다. 'ref'가 변경됩니다 전화 컨벤션 그러나 아닙니다 유형 매개 변수의. C ++ 예제에서 D1과 D2는 int*유형입니다. C#에서는 여전히 int32입니다. 값 대신 참조로 전달됩니다.

그건 그렇고, C ++ 코드는 전통적인 의미에서 입력을 실제로 교체하지 않습니다. 그렇게 일반화 :

template<typename T>
void swap(T *d1, T *d2)
{
    T temp = *d1;
    *d1 = *d2;
    *d2 = temp;
}

... 모든 유형 t에 사본 생성자가 없으면 작동하지 않으며 심지어 포인터를 바꾸는 것보다 훨씬 비효율적입니다.

짧은 대답은 예입니다 (유사한 기능이지만 정확히 동일한 메커니즘은 아닙니다). 참고로, FXCOP를 사용하여 코드를 분석하는 경우 out 그리고 ref "Microsoft.Design"오류 "CA1045 : DonotpasStypesByference"의 오류가 발생합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top