JAVA 멍충이 탈출기 5

sein lee·2024년 4월 4일
0

java-study

목록 보기
3/12
post-thumbnail
post-custom-banner

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

변수는 선언한 위치에 따라 지역 변수, 멤버 변수(클래스 변수, 인스턴스 변수)와 같이 분류된다.
지역 변수는 이름 그대로 특정 지역에서만 사용할 수 있는 변수라는 뜻이다. 그 특정 지역을 벗어나면 사용할 수 없다.
여기서 말하는 지역이 바로 변수가 선언된 코드 블록( {} ) 이다. 지역 변수는 자신이 선언된 코드 블록( {} ) 안에서만 생
존하고, 자신이 선언된 코드 블록을 벗어나면 제거된다.

<Scope1.java>

package scope;

public class Scope1 {
    public static void main(String[] args) {
        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); //오류, 변수 x에 접근 불가
        System.out.println("main m = " + m);
    } //m 종료
}
  • int m
    => main{}의 코드 블록안에서 선언 , if{}블록 내부에서도 m 에 접근가능
  • int x
    => if{} 블록안에서 선언

변수의 접근 가능한 범위를 스코프(Scope) 라 한다.

<Scope2.java>

package scope;

public class Scope2 {
    public static void main(String[] args) {
        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 - 스코프 존재 이유

<Scope3_1.java>

package scope;

public class Scope3_1 {
    public static void main(String[] args) {
        int m=10;
        int temp=0;
        if(m>0){
            temp = m*2;
            System.out.println("temp = " +temp);
        }
        System.out.println("m = "+m);
    }
}

=> temp 는 if 조건이 만족할 때 임시로 잠깐 사용하는 변수이다. 그런데 임시 변수를 main()에 선언하기 되면 다음과 같은 문제가 발생한다.

  • 비효율적인 메모리 사용
  • 코드 복잡성 증가
    <Scope3_2.java>로 보완
package scope;

public class Scope3_2 {
    public static void main(String[] args) {
        int m = 10;
        if (m > 0) {
            int temp = m * 2;
            System.out.println("temp = " + temp);
        }
        System.out.println("m = " + m);
    }
}

형변환1 - 자동 형변환

형변환

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

<Casting1.java>
-> 작은 범위에서 큰 범위에 값을 대입

package scope;

public class Casting1 {
    public static void main(String[] args) {
        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
    }
}

<결과>

자동 형변환 (묵시적 형변환)

//intValue = 10
doubleValue = intValue
doubleValue = (double) intValue //형 맞추기
doubleValue = (double) 10 //변수 값 읽기
doubleValue = 10.0 //형변환

=> (double)과 같이 적어주면 int형이 double형으로 변한다.

형변환2 - 명시적 형변환

큰 범위에서 작은 범위 대입은 명시적 형변환이 필요하다.
double-> int ?
<Casting2.java>

package scope;

public class Casting2 {
    public static void main(String[] args) {
        double doubleValue = 1.5;
        int intValue = 0;

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

    }
}

명시적 형변환 과정

//doubleValue = 1.5
intValue = (int) doubleValue;
intValue = (int) 1.5; //doubleValue에 있는 값을 읽는다.
intValue = 1; //(int)로 형변환 한다. intValue에 int형인 숫자 1을 대입한다.

형변환과 오버플로우

형변환을 할 때 작은숫자가 표현할수 있는 범위를 넘어서면 어떻게 될까?
<Casting3.java>

package scope;

public class Casting3 {
    public static void main(String[] args) {
        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 => 오버플로우
        
    }
}

<결과>

=> maxIntOver는 int로 표현 할 수 있는 가장 큰 숫자보다 1이 큼 -> 오버플로우 발생 -> intValue의 타입을 int에서 long 으로 변경

계산과 형변환

<Casting4.java>

package scope;

public class Casting4 {
    public static void main(String[] args) {
        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) a / b;
        System.out.println("result = " + result); //1.5
    }
}

<결과>

  1. 같은 타입끼리의 계산은 같은 타입의 결과를 낸다.
  2. 서로 다른 타입의 계산은 큰 범위로 자동 형변환이 이루어진다.
    int + long -> long + long
    int + double -> double + double
int div1 = 3 / 2; //int / int
int div1 = 1; //int / int이므로 int타입으로 결과가 나온다.
double div2 = 3 / 2; //int / int
double div2 = 1; //int / int이므로 int타입으로 결과가 나온다.
double div2 = (double) 1; //int -> double에 대입해야 한다. 자동 형변환 발생
double div2 = 1.0; // 1(int) -> 1.0(double)로 형변환 되었다.
double div3 = 3.0 / 2; //double / int
double div3 = 3.0 / (double) 2; //double / int이므로, double / double로 형변환이 발생한다.
double div3 = 3.0 / 2.0; //double / double -> double이 된다.
double div3 = 1.5;
double div4 = (double) 3 / 2; //명시적 형변환을 사용했다. (double) int / int
double div4 = (double) 3 / (double) 2; //double / int이므로, double / double로 형변환이 발생한다.
double div4 = 3.0 / 2.0; //double / double -> double이 된다.
double div4 = 1.5;

정리

int -> long -> double

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

0개의 댓글