연습 - 값 및 참조 형식 매개 변수 사용

완료됨

C#에서 변수는 두 가지 기본 형식, 값 형식 및 참조 형식으로 분류할 수 있습니다. 이러한 형식은 변수가 해당 값을 저장하는 방법을 설명합니다.

값 형식(예: int, bool, float, double, 및 char)은 값을 직접 포함합니다. 참조 형식(예: string, array, 그리고 Random의 인스턴스와 같은 개체)은 해당 값을 직접 저장하지 않습니다. 대신 참조 형식은 해당 값이 저장되는 주소를 저장합니다.

값으로 전달되고 참조로 전달되는 매개 변수

인수가 메서드에 전달되면 형식 변수의 값이 메서드에 복사됩니다. 각 변수에는 값의 자체 복사본이 있으므로 원래 변수는 수정되지 않습니다.

참조 형식을 사용하면 값의 주소가 메서드에 전달됩니다. 메서드에 지정된 변수는 해당 주소의 값을 참조하므로 해당 변수에 대한 작업은 다른 변수가 참조하는 값에 영향을 줍니다.

비고

string이라는 점을 기억하는 것이 중요합니다. 이는 참조 형식이지만 변경할 수 없습니다. 즉, 값이 할당되면 변경할 수 없습니다. C#에서 메서드와 연산자를 사용하여 문자열을 수정하는 경우 반환되는 결과는 실제로 새 문자열 개체입니다.

이 연습에서는 메서드에 참조 및 값 형식 인수를 전달하는 방법에 대해 자세히 알아봅니다.

값별 테스트 통과

  1. Visual Studio Code 편집기에서 이전 연습의 기존 코드를 모두 삭제합니다.

  2. Visual Studio Code 편집기에 다음 코드를 입력합니다.

    int a = 3;
    int b = 4;
    int c = 0;
    
    Multiply(a, b, c);
    Console.WriteLine($"global statement: {a} x {b} = {c}");
    
    void Multiply(int a, int b, int c) 
    {
        c = a * b;
        Console.WriteLine($"inside Multiply method: {a} x {b} = {c}");
    }
    

    변수 a, b, cMultiply 메서드에 전달됩니다. 변수 값은 메서드 실행 중에 인쇄되고 메서드가 완료된 후에 다시 인쇄됩니다.

    정수는 메서드로 전달될 때 해당 값이 복사되는 값 형식입니다. c의 출력은 무엇이라고 생각하나요?

  3. 코드를 저장하고 실행하여 다음 출력을 관찰합니다.

    inside Multiply method: 3 x 4 = 12
    global statement: 3 x 4 = 0
    

    유의하세요 c 값은 Multiply 메소드 내에서만 변경됩니다. 메서드 c 외부에서 원래 값을 유지합니다.

참조 전달 테스트

  1. Visual Studio Code 편집기에서 이전 코드를 삭제합니다.

  2. Visual Studio Code 편집기에 다음 코드를 입력합니다.

    int[] array = {1, 2, 3, 4, 5};
    
    PrintArray(array);
    Clear(array);
    PrintArray(array);
    
    void PrintArray(int[] array) 
    {
        foreach (int a in array) 
        {
            Console.Write($"{a} ");
        }
        Console.WriteLine();
    }
    
    void Clear(int[] array) 
    {
        for (int i = 0; i < array.Length; i++) 
        {
            array[i] = 0;
        }
    }
    

    코드는 일부 정수 값을 포함하도록 초기화된 것으로 시작 array 합니다. PrintArray 메서드를 사용하여 값이 표시됩니다. Clear 배열에서 메서드가 호출된 다음 배열이 다시 인쇄됩니다.

    배열은 참조 형식입니다. 참조 형식은 해당 값의 주소를 메모리에 저장합니다. 출력은 어떻게 될 것이라고 생각하십니까?

  3. 코드를 저장하고 실행하여 다음 출력을 관찰합니다.

    1 2 3 4 5 
    0 0 0 0 0
    

    배열은 Clear 메서드 범위 외부에서도 변경된 상태로 유지됩니다. 이 문제는 메서드가 Clear 각 주소에 저장된 값을 업데이트했기 때문에 발생합니다.

문자열로 테스트

이전에는 문자열이 변경할 수 없는 형식이라는 것을 배웠습니다. 문자열이 참조 형식이더라도 배열과 달리 문자열이 할당된 후에는 해당 값을 변경할 수 없습니다. 와 같은 string.Replacestring.ToUpper메서드를 사용한 경우 이를 알아차렸을 수 있습니다. 이 작업에서는 문자열로 작업할 때 발견되는 일반적인 오류를 수정하는 방법을 알아봅니다.

  1. Visual Studio Code 편집기에서 이전 연습의 기존 코드를 모두 삭제합니다.

  2. Visual Studio Code 편집기에 다음 코드를 입력합니다.

    string status = "Healthy";
    
    Console.WriteLine($"Start: {status}");
    SetHealth(status, false);
    Console.WriteLine($"End: {status}");
    
    void SetHealth(string status, bool isHealthy) 
    {
        status = (isHealthy ? "Healthy" : "Unhealthy");
        Console.WriteLine($"Middle: {status}");
    }
    
  3. 코드를 저장하고 실행하여 다음 출력을 관찰합니다.

    Start: Healthy
    Middle: Unhealthy
    End: Healthy
    

    메서드가 SetHealth 상태를 출력하지 않은 경우 메서드가 올바르게 실행되지 않았다고 가정했을 수 있습니다. 대신 값이 "비건전"인 새 문자열이 생성된 다음 메서드의 범위 내에서 사라졌습니다.

    이 문제를 해결하려면 전역 상태 변수를 대신 사용하도록 변경할 SetHealth 수 있습니다.

  4. 다음과 같이 코드를 업데이트합니다.

    string status = "Healthy";
    
    Console.WriteLine($"Start: {status}");
    SetHealth(false);
    Console.WriteLine($"End: {status}");
    
    void SetHealth(bool isHealthy) 
    {
        status = (isHealthy ? "Healthy" : "Unhealthy");
        Console.WriteLine($"Middle: {status}");
    }
    

    이 코드에서는 새 문자열 값으로 전역 status 변수를 덮어씁 수 있습니다.

  5. 코드를 저장하고 실행하여 다음 출력을 관찰합니다.

    Start: Healthy
    Middle: Unhealthy
    End: Unhealthy
    

    이제 업데이트된 문자열이 캡처되고 올바르게 저장됩니다.

요약

지금까지 값 형식 및 참조 형식 매개 변수에 대해 알아본 내용은 다음과 같습니다.

  • 변수는 값 형식 및 참조 형식으로 분류할 수 있습니다.
  • 값 형식에는 값이 직접 포함되고 참조 형식은 값의 주소를 저장합니다.
  • 값 형식 인수를 사용하는 메서드는 값의 자체 복사본을 만듭니다.
  • 배열 매개 변수에 대한 변경 내용을 수행하는 메서드는 원래 입력 배열에 영향을 줍니다.
  • 문자열은 변경할 수 없는 참조 형식입니다.
  • 문자열 매개 변수를 변경하는 메서드는 원래 문자열에 영향을 주지 않습니다.