ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • JAVA - 스코프(Scope), 형변환
    JAVA 2023. 12. 18. 22:37
    728x90

    1. 스코프 - 지역 변수와 스코프

    변수는 선언한 위치에 따라

     

     - 지역 변수

     - 멤버 변수(클래스 변수, 인스턴스 변수)

     

    로 나뉜다. (멤버 변수는 뒤에서 다시 다뤄볼 예정)

     

    지역변수

     - 자신이 선언된 코드 블록( {} ) 안에서만 생존하고, 자신이 선언된 코드 블록을 벗어나면 제거된다. 따라서 이후에는 접근할 수 없다.

     

     - if{} 를 사용한 예시

    int m = 10; // m 생존 시작
            if (true) {
                int x = 20; // x 생존 시작
                System.out.println("if m = " + m);
                System.out.println("if x = " + x);
            } // x 생존종료
            //System.out.println("main x = " + x);
            System.out.println("main m = " + m);
        } // m 생존 종료

     

    이렇게 변수의 접근 가능한 범위를 스코프라고 한다.

     

    - for{}를 사용하는 예시

    int m = 10;
            for (int i = 0; i < 2; i++) { // 블록 내부, for문 내
                System.out.println("for m : " + m); // 블록 내부에서 외부는 접근 가능
                System.out.println("for i : " + i);
            } // i 생존 종료
            //System.out.println("main i = " + i); // 오류, i에 접근 불가
            System.out.println("main m = " + m);
        }

     

    2. 스코프의 존재 이유

    int m = 10;
    int temp = 0;
    if (m > 0) {
        temp = m * 2;
        System.out.println("temp = " + temp);
    }
    System.out.println("m = " + m);

     

     - temp는 if문 안에서 사용하지만 위와 같이 if 전역적(main 코드블록)으로 선언이 되어 있으면 다음과 같은 문제가 발생한다.

     

    1. 비효율적인 메모리 사용

     - temp는 if 코드 블록에서만 필요하지만, main() 코드 블록이 종료될 때까지 메모리에 유지된다. 따라서 불필요한 메모리가 낭비되므로, fi 코드 블록 안에 temp를 선언했다면 더 효율적으로 메모리를 사용할 수 있다.

     

    2. 코드 복잡성 증가

     - 만약 if 코드 블록안에 temp를 선언했다면 if가 끝나고 나면 temp를 전혀 생각하지 않아도 된다. 하지만 위 코드는 if 코드 블록이 끝나도 m 과 temp 두 가지 변수를 모두 생각해야 하기 때문이다.

     

    아래 코드는 필요한 곳으로 한정되게 바꿔본 코드이다.

     

    int m = 10;
    if (m > 0) {
        int temp = m * 2;
        System.out.println("temp = " + temp);
    }
    System.out.println("m = " + m);

     

     

     

    >> 변수는 꼭 필요한 범위로 한정해서 사용하는 것이 좋다. 변수의 스코프는 꼭 필요한 곳으로 한정해서 사용해야 한다. 메모리를 효율적으로 사용하고 더 유지보수하기 좋은 코드로 만들 수 있다.

    >> 좋은 프로그램은 무한한 자유가 있는 프로그램이 아니라 적절한 제약이 있는 프로그램이다.

     

     

    3-1. 형변환 - 자동 형변환

    • 작은 법위에서 큰 범위로는 당연히 값을 넣을 수 있다.
      • int -> long -> double
    • 큰 범위에서 작은 범위는 다음과 같은 문제가 발생할 수 있다
      • 소수점 버림
      • 오버플로우

    작은 범위에서 큰 범위로 대입은 허용한다.

    int intValue = 10;
    long longValue;
    double doubleValue;
    
    longValue = intValue; // int -> long
    System.out.println("longValue = " + longValue); //longValue = 10
    
    doubleValue = intValue; // int -> double
    System.out.println("doubleValue1 = " + doubleValue); //doubleValue1 = 10.0
    
    doubleValue = 20L; // long -> double
    System.out.println("doubleValue2 = " + doubleValue); //doubleValue2 = 20.0

     

    작은 범위 숫자 타입에서 큰 범위 숫자 타입으로의 대입은 개발자가 이렇게 직접 형변환을 하지 않아도 된다. 이런 과정이 자동으로 일어나기 때문에 자동 형변환, 또는 묵시적 형변환이라 한다.

     

    3-2. 형변환 - 명시적 형변환

     

    큰 범위에서 작은 범위 대입은 명시적 형변환이 필요하다.

     

    double doubleValue = 1.5;
    int intValue = 0;
    //intValue = doubleValue; //컴파일 오류 발생
    intValue = (int) doubleValue; //형변환
    System.out.println(intValue); //출력:1

     

    명시적 형변환(영어로는 casting) - 개발자가 직접 형변환 코드를 입력하는 것

     

    형변환과 오버플로우

     

     형변환을 할 때 만약 작은 숫자가 표현할 수 있는 범위를 넘어선다면??

    long maxIntValue = 2147483647; //int 최고값
    long maxIntOver = 2147483648L; //int 최고값 + 1(초과)
    int intValue = 0;
    
    intValue = (int) maxIntValue; //형변환
    System.out.println("maxIntValue casting=" + intValue); //출력:2147483647
    
    intValue = (int) maxIntOver; //형변환
    System.out.println("maxIntOver casting=" + intValue); //출력:-2147483648 }

     

    정상범위 안에 들어가 있는 maxIntValue는 상관없지만, 정상범위를 넘어선 maxIntOver 같은 경우에는 시계가 한 바퀴 돈 것처럼 다시 시작한다.

     >> 즉, int의 범위는 -2147483648~2147483647 인데 최대 범위에서 1이 넘어선 숫자가 나오니 최대 범위에서 한 칸 움직여서 int의 시작으로 온 것이다.

     

    계산과 형변환

     

    int div1 = 3 / 2;
    System.out.println("div1 = " + div1); // 1
    
    double div2 = 3 / 2;
    System.out.println("div2 = " + div2); // 1.0
    
    double div3 = 3.0 / 2;
    System.out.println("div3 = " + div3); // 1.5
    
    double div4 = (double) 3 / 2;
    System.out.println("div4 = " + div4); // 1.5
    
    int a = 3;
    int b = 2;
    
    double result = (double) 3 / 2;
    System.out.println("result = " + result);

     

    자바에서의 계산은 2가지만 기억하면 된다.

    1. 같은 타입끼리의 계산은 같은 타입의 결과를 낸다.

      - int + int는 int / double + double = double

    2. 서로 다른 타입의 계산은 큰 범위로 자동 형변환이 일어난다.

      - int + long = long + long / int + double = double + double

     

    정리

     형변환

      int -> long -> double

    • 작은 범위에서 큰 범위로는 대입할 수 있다
      • 이것이 묵시적 형변환 또는 자동 형변환이라고 한다.
    • 큰 범위에서 작은 범위의 대입은 다음과 같은 문제가 발생할 수 있다. 이때는 명시적 형변환을 사용해야 한다.
      • 소수점 버림
      • 오버플로우
    • 연산과 형변환
      • 같은 타입은 같은 결과를 낸다.
      • 서로 다른 타입의 계산은 더 큰 범위로 자동 형변환이 일어난다.

    'JAVA' 카테고리의 다른 글

    JAVA - 배열  (0) 2023.12.28
    JAVA - Scanner사용 및 훈련  (1) 2023.12.27
    JAVA - 반복문  (1) 2023.12.18
    JAVA - 조건문  (0) 2023.12.17
    JAVA - 변수 , 연산자  (0) 2023.12.14
Designed by Tistory.