본문 바로가기

항해 99/Java

Java 기초 3 - 반복문, 스코프, 형변환

반복문

반복문은 특정 코드를 반복해서 실행할 때 사용.

자바에서 제공하는 반복문은 3가지 종류가 있음

 

while , do-while , for

 

while

while (조건식) {
	// 코드
}
  • 조건식을 확인한다. 참이면 코드 블럭을 실행하고, 거짓이면 while문을 벗어난다.
  • 조건식이 참이면 코드 블럭을 실행한다. 이후에 코드 블럭이 끝나면 다시 조건식 검사로 돌아가서 조건식을 검사한다. (무한반복)
package loop;

public class While_2 {

    public static void main(String[] args) {
        int count = 0;

        while (count < 3) {
            count++;
            System.out.println("현재 숫자는:" + count);
        }

    }
}
  • while (count < 3)에서 코드 블럭을 반복 실행한다. 여기서 count의 값이 1, 2, 3으로 점점 커지다가 결국 count < 3이 거짓이 되면 while문을 빠져나간다.
  • while (count < 3)의 숫자를 바꾸면 바뀐 숫자 만큼 코드 블럭을 반복한다. 

while문을 사용하여 i 값부터 endNum만큼 반복해서 더하는 코드 작성 

package loop;

public class while2_3 {

    public static void main(String[] args) {
        int sum = 0;
        int i = 1;
        int endNum = 3;

        while (i <= endNum) {
            sum = sum +i;
            System.out.println("i=" + i + " sum=" + sum);
            i++;
        }
    }
}

 

반복 횟수 정하기

i가 endNum이 될 때까지 반복해서 코드를 실행하면 된다.

  • i = 1, endNum=3이라면 3번 반복하면 된다.
  • i = 3, endNum=4라면 2번 반복하면 된다.

while문 작성하기

  • while문에서 i <= endNum 조건을 통해 i가 endNum이 될 때까지 코드 블럭을 실행한다.
  • i가 endNum보다 크면 while문을 종료한다.

 

do-while문

do-while문은 while문과 비슷하지만, 조건에 상관없이 무조건 한 번은 코드를 실행한다.

 

do-while문 구조

do {
	// 코드
} while (조건식);

 

조건에 만족하지 않아도 한 번은 현재 값을 출력하고 싶은 경우 do-while문을 사용

package loop;

public class DoWhile1 {

    public static void main(String[] args) {
        int i = 10;

            do {
                System.out.println("현재 숫자는:" + i);
                i++;
        } while (i < 3);
    }
}

 

  • do-while문은 최초 한 번은 항상 실행된다. 코드 블럭을 실행 후에 조건식을 검증하여, 조건식이 거짓일 경우 do-while문을 빠져나온다.

break, continue

  • break와 continue는 반복문에서 사용할 수 있는 키워드.
  • break는 반복문을 즉시 종료하고 나간다. continue는 반복문의 나머지 부분을 건너뛰고 다음 반복으로 진행하는데 사용됨.
  • break와 continue는 모든 반복문에서 사용 가능하다.

break

while(조건식) {
	코드 1;
    break; // 즉시 while문 종료로 이동한다.
    코드 2;
}
// while문 종료

 

break를 만나면 코드2가 실행되지 않고 while문이 종료됨.

 

continue

while(조건식) {
	코드 1;
    continue; //즉시 조건식으로 이동한다.
    코드 2;
}
// while문 종료

 

continue를 만나면 코드2가 실행되지 않고 다시 조건식으로 이동한다. 조건식이 참이면 while문을 실행한다.

 

break

package loop;

public class Break1 {

    public static void main(String[] args) {
        int sum = 0;
        int i = 1;

        while(true) {
            sum = sum + i;
            if (sum > 10) {
                System.out.println("합이 10보다 크면 종료: i=" + " sum=" + sum);
                break;
            }
            i++;
        }
    }
}
  • 조건식이 true일 경우, 조건이 항상 참이기 때문에 while문이 무한 반복된다. break문이 있으면 중간에 빠져 나올 수 있다.
  • sum > 10 조건을 만족하면 결과를 출력하고, break를 사용해서 while문을 빠져 나간다.

continue

package loop;

public class Continue1 {

    public static void main(String[] args) {
        int i = 1;

        while (i <=5) {
            if (i == 3) {
                i++;
                continue;
            }
            System.out.println(i);
            i++;
        }
    }
}

 

i==3인 경우 i를 하나 증가하고 continue를 실행한다. 이 때는 i를 출력하지 않고 바로 while ( i <= 5) 조건식으로 이동한다.

 

for문

while문과 같은 반복문이며, 코드를 반복 실행하는 역할을 한다. 주로 반복 횟수가 정해져 있을 때 사용한다.

 

for문 구조

for (1. 초기식; 2.조건식; 4.증감식) {
	// 3.코드
}

 

for문은 다음 순서대로 실행된다.

  • 1. 초기식이 실행된다. 주로 반복 횟수와 관련된 변수를 선언하고 초기화 할 때 사용한다. 초기식은 딱 1번 사용됨.
  • 2. 조건식을 검증한다. 참이면 코드를 실행하고, 거짓이면 for문을 빠져나간다.
  • 3. 코드를 실행한다.
  • 4. 코드가 종료되면 증감식을 실행한다. 주로 초기식에 넣은 반복 횟수와 관련된 변수의 값을 증가할 때 사용한다.
  • 5. 다시 2. 조건식부터 시작한다. (무한 반복)

for문은 복잡해 보이지만 while문을 조금 더 편하게 다룰 수 있도록 구조화 한 것.

// i가 10 이하일 때만 실행되는 반복문
package loop;

public class For1 {

    public static void main(String[] args) {
        for (int i = 1; i <= 10; i++) {
            System.out.println(i);
        }
    }
}

// i가 endNum이하일 때만 실행되는 반복문
package loop;

public class For2 {

    public static void main(String[] args) {
        int sum = 0;
        int endNum = 3;

        for (int i = 1; i <= endNum; i++) {
            sum = sum + i;
            System.out.println("i=" + i + " sum=" + sum);
        }
    }
}

 

for vs while

// for문
package loop;

public class For2 {

    public static void main(String[] args) {
        int sum = 0;
        int endNum = 3;

        for (int i = 1; i <= endNum; i++) {
            sum = sum + i;
            System.out.println("i=" + i + " sum=" + sum);
        }
    }
}


// while문
package loop;

public class while2_3 {

    public static void main(String[] args) {
        int sum = 0;
        int i = 1;
        int endNum = 10;

        while (i <= endNum) {
            sum = sum +i;
            System.out.println("i=" + i + " sum=" + sum);
            i++;
        }
    }
}

 

둘 코드 비교 시 for문이 더 깔끔한 느낌이 난다. for문은 초기화, 조건 검사, 반복 후 작업 등이 규칙적으로 한 줄에 모두 들어 있어 코드를 이해하기 더 쉽다. 특히 반복을 위해 값이 증가하는 카운터 변수를 다른 부분과 명확하게 구분할 수 있다.

 

for문에서 초기식, 조건식, 증감식은 선택이다. 단 생략해도 각 영역을 구분하는 세미콜론( ; )은 유지해야 한다.

for (;;) {
	//코드
}
  • 조건이 없기 때문에 무한 반복하는 코드가 된다.
package loop;

public class Break2 {

    public static void main(String[] args) {
        int sum = 0;
        int i = 1;

        for(;;) {
            sum = sum + i;
            if (sum > 10) {
                System.out.println("합이 10보다 크면 종료: i=" + " sum=" + sum);
                break;
            }
            i++;
        }
    }
}
  • for ( ; ; )는 조건식이 없기 때문에 무한 반복한다.
  • sum > 10 조건을 만족하면 break를 사용해서 for문을 빠져 나온다.

for문은 증가하는 값이 무엇인지 초기식과 증감식을 통해서 쉽게 확인할 수 있음. 위 코드나 while문을 보면 어떤 값이 반복에 사용되는 증가 값인지 즉시 확인하기는 어렵다.

package loop;

public class Break3 {

    public static void main(String[] args) {
        int sum = 0;

        for(int i=1;;i++) {
            sum = sum + i;
            if (sum > 10) {
                System.out.println("합이 10보다 크면 종료: i=" + " sum=" + sum);
                break;
            }
        }
    }
}

 

for문 없이 while문으로 모든 반복을 다룰 수 있지만, 카운터 변수가 명확하거나 반복 횟수가 정해진 경우에는 for문을 사용하는 것이 구조적으로 더 깔끔하고, 유지보수 하기 좋다.

 

중첩 반복문

반복문 내부에 또 반복문을 만들 수 있다. for, while 모두 가능하다.

package loop;

public class Nested1 {

    public static void main(String[] args) {
        for (int i = 0; i < 2; i++) {
            System.out.println("외부 for 시작 i:" + i);
            for (int j = 0; j < 3; j++) {
                System.out.println("-> 내부 for " + i + "-" + j);
            }
            System.out.println("외부 for 종료 i:" + i);
            System.out.println();
        }
    }
}

 

문제

1. 반복문으로 1부터 10까지 출력

package loop.ex;

public class WhileEx1 {

    public static void main(String[] args) {
        // while
        int count = 1;

        while (count <= 10) {
            System.out.println("while:" + count);
            count++;
        }
    }
}


package loop.ex;

public class ForEx1 {

    public static void main(String[] args) {
        // for
        for (int count= 1; count <= 10; count++) {
            System.out.println("for:" + count);
        }
    }
}

 

2. 짝수 10개 출력

package loop.ex;

public class WhileEx2 {

    public static void main(String[] args) {
        int count = 1;
        int num = 1;

        while (count <= 10) {
            num++;
            if (num % 2 == 0) {
                System.out.println("짝수 출력:" + num);
                count++;
            }
        }
    }
}


package loop.ex;

public class ForEx2 {

    public static void main(String[] args) {
        for (int num=1, count=1; count <= 10; num++) {
            if (num % 2 == 0) {
                System.out.println("짝수 출력:" + num);
                count++;
            }
        }
    }
}

 

3. 누적합 계산

package loop.ex;

public class WhileEx3 {

    public static void main(String[] args) {
        int i = 1;
        int max = 10;
        int sum = 0;

        while (i <= max) {
            sum = sum +i;
            i++;
        }
        System.out.println("sum=" + sum);
    }
}

package loop.ex;

public class ForEx3 {

    public static void main(String[] args) {
        int max = 100;
        int sum = 0;
        for (int i = 1; i <= max; i++) {
            sum += i;
        }
        System.out.println("sum=" + sum);
    }
}

 

4. 구구단 출력

package loop.ex;

public class NestedEx1 {

    public static void main(String[] args) {

        for (int i = 1; i <= 9; i++) {
            for (int j = 1; j <= 9; j++) {
                int result = i*j;
                System.out.println(i + "*" + j + "=" + result);
            }
        }
    }
}

 

5. 피라미드 출력

package loop.ex;

public class NestedEx2 {

    public static void main(String[] args) {
        for (int i=1, rows=5; i<=rows; i++) {
            for (int j=1; j<=i; j++) {
                System.out.print("*");
            }
            System.out.println();
        }
    }
}

 

정리

for문

장점:

  1. 초기화, 조건 체크, 반복 후의 작업을 한 줄에서 처리할 수 있어 편리하다.
  2. 정해진 횟수만큼의 반복을 수행하는 경우에 사용하기 적합하다.
  3. 루프 변수의 범위가 for 루프 블록에 제한되므로, 다른 곳에서 이 변수를 실수로 변경할 가능성이 적다.

단점:

  1. 루프의 조건이 루프 내부에서 변경되는 경우, for 루프는 관리하기 어렵다.
  2. 복잡한 조건을 가진 반복문을 작성하기에는 while문이 더 적합할 수 있다.

While문

장점:

  1. 루프의 조건이 루프 내부에서 변경되는 경우, while 루프는 이를 관리하기 쉽다.
  2. for 루프보다 더 복잡한 조건과 시나리오에 적합하다.
  3. 조건이 충족되는 동안 계속해서 루프를 실행하며, 종료 시점을 명확하게 알 수 없는 경우에 유용하다.

단점:

  1. 초기화, 조건 체크, 반복 후의 작업이 분산되어 있어 코드를 이해하거나 작성하기 어려울 수 있다.
  2. 루프 변수가 while 블록 바깥에서도 접근 가능하므로, 이 변수를 실수로 변경하는 상황이 발생할 수 있다.

한줄로 정리하자면 정해진 횟수만큼 반복을 수행해야 하면 for문을 사용하고 그렇지 않으면 while문을 사용하면 된다.
물론 이것이 항상 정답은 아니니 기준으로 삼는 정도로 이해하자

 

 

스코프, 형변환

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

변수는 선언한 위치에 따라 지역 변수, 멤버 변수(클래스 변수, 인스턴스 변수)와 같이 분류된다.

 

로컬 변수(Local Variable)

지역 변수는 이름 그대로 특정 지역에서만 사용할 수 있는 변수라는 뜻이다. 그 특정 지역을 벗어나면 사용할 수 없다.
여기서 말하는 지역이 바로 변수가 선언된 코드 블록(  {}  )이다. 지역 변수는 자신이 선언된 코드 블록(  {}  ) 안에서만 생
존하고, 자신이 선언된 코드 블록을 벗어나면 제거된다. 따라서 이후에는 접근할 수 없다.

 

scope

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 m =" + m);
        //System.out.println("main x =" + x);
    } // m 생존 종료
}
  • int m
    • int m은 main{ }의 코드 블록안에서 선언되었다. 따라서 변수를 선언한 시점부터 main{ }의 코드 블
      록이 종료될 때 까지 생존한다.
    • if { } 블록 내부에서도 외부 블록에서 선언된 m 에 접근할 수 있다. 쉽게 이야기해서 생존 범위만 맞으면 다
      접근할 수 있다.
  • int x
    • int x는 if { }블록안에서 선언되었다. 따라서 변수를 선언한 시점부터 if { }의 코드 블록이 종료될 때
      까지 생존한다.
    • if { } 내부에서는 자신의 범위에서 선언한 x 에 당연히 접근할 수 있다.
    • if { } 코드 블록이 끝나버리면 x 는 제거된다. 따라서 더는 x 에 접근할 수 없다. 따라서 이후에 접근하면cannot find symbol이라는 변수 이름을 찾을 수 없다는 컴파일 오류가 발생한다.

지역 변수는 본인의 코드 블록 안에서만 생존한다. 자신의 코드 블록 안에서는 얼마든지 접근할 수 있다. 하지만 자신의 코드블록을 벗어나면 제거되기 때문에 접근할 수 없다.

 

이렇게 변수의 접근 가능한 범위를 스코프(Scope)라 한다. 참고로 Scope를 번역하면 범위라는 뜻이다.

int m 은 main{ } 전체에서 접근할 수 있기 때문에 스코프가 넓고, int x 는 if { } 코드 블록 안에서만 접근할 수 있기 때문에 스코프가 좁다.

 

scope2

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 m =" + m);
        //System.out.println("main i =" + i);
    }
}

 

스코프 존재 이유

scope3_1

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);
    }
}

 

조건이 맞으면 m의 값을 2배 증가해서 출력하는 코드, 임시변수 temp가 main { } 코드 블록에 선언되어 있어서 몇 가지 문제가 발생한다.

  • 비효율적인 메모리 사용: temp는 if 코드 블록에서만 필요한데, main { } 코드 종료될 때 까지 메모리에 유지됨, 따라서 불필요하게 메모리가 낭비된다. if 코드 블록 내에서 temp를 선언하면 더 효율적으로 메모리를 사용할 수 있다.
  • 코드 복잡성 증가: 좋은 코드는 군더더기 없이 단순한 코드이다. temp는 if 코드 블록에서만 필요하고 사용된다. 하지만 위 코드에서는 main { } 어디서나 temp에 접근할 수 있기 때문에 유지보수할 때 m과 temp 모두 신경 써야 함. 코드가 복잡해질 수록 이해하는데 어려움이 생긴다.

scope3_2

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("temp = " + temp);
        System.out.println("m = " + m);
    }
}
  • temp if  코드 블록 안에서 선언하면서 temp는 if 코드 블록 안으로 스코프가 줄어든다. temp 메모리를 빨리 제거해서 메모리를 효율적으로 사용하고, temp 변수를 생각해야 하는 범위를 줄여서 더 유지보수하기 좋은 코드가 됨.

while문 vs for문 - 스코프 관점

스코프 관점에서 while문과 for문 비교

 

while

package loop;

public class while2_3 {

    public static void main(String[] args) {
        int sum = 0;
        int i = 1;
        int endNum = 10;

        while (i <= endNum) {
            sum = sum +i;
            System.out.println("i=" + i + " sum=" + sum);
            i++;
        }
    }
}

 

for

package loop;

public class For2 {

    public static void main(String[] args) {
        int sum = 0;
        int endNum = 3;

        for (int i = 1; i <= endNum; i++) {
            sum = sum + i;
            System.out.println("i=" + i + " sum=" + sum);
        }
    }
}

 

변수의 스코프 관점에서 카운터 변수 i 비교

  • while문의 경우 변수 i의 스코프가 main( ) 메서드 전체가 된다. 반면에 for 문의 경우 변수 i의 스코프가 for문 안으로 한정된다.
  • 따라서 변수 i와 같이 for문 안에서만 사용되는 카운터 변수가 있다면 while문보다 for문을 사용해서 스코프의 범위를 제한하는 것이 메모리 사용과 유지보수 관점에서 더 좋다.

정리

  • 변수는 꼭 필요한 범위로 한정해서 사용하는 것이 좋다. 변수의 스코프는 꼭 필요한 곳으로 한정해서 사용하자. 메모리를 효율적으로 사용하고 더 유지보수하기 좋은 코드를 만들 수 있다.
  • 좋은 프로그램은 무한한 자유가 있는 프로그램이 아니라 적절한 제약이 있는 프로그램이다.

 

형변환 - 자동 형변환

형변환

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

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

자바의 숫자를 표현할 수 있는 범위

int < long < double

 

작은 범위에서 큰 범위에 값을 대입하는 코드는 특별한 문제 없이 잘 수행됨.

 

 

Casting1

package casting;

public class Casting1 {

    public static void main(String[] args) {
        int intValue = 10;
        long longValue;
        double doubleValue;
        
        longValue = intValue;
        System.out.println("longValue = " + longValue);

        doubleValue = intValue;
        System.out.println("doubleValue = " + doubleValue);

        doubleValue = 20L;
        System.out.println("doubleValue2 = " + doubleValue);
    }
}
  • 자바는 기본적으로 같은 타입에 값을 대입할 수 있다.
  • int long 을 비교해보면 long 이 int 보다 더 큰 숫자 범위를 표현한다. 작은 범위 숫자 타입에서 큰 범위 숫자 타입에 대입을 하면 문제가 되지 않는다. 만약 이런 경우까지 오류가 발생한다면 개발이 너무 불편할 것이다.
  • long double 의 경우에도 double 은 부동 소수점을 사용하기 때문에 더 큰 숫자 범위를 표현한다. 따라서 대입할 수 있다.
  • 정리하면 작은 범위에서 큰 범위로의 대입은 자바 언어에서 허용한다. 쉽게 이야기하면 큰 그릇은 작은 그릇에 담긴 내용물을 담을 수 있다.

 

자동형변환

대입하는 형(타입)을 맞추어야 하기 때문에 개념적으로는 다음과 같이 동작한다.

//intValue = 10
doubleValue = intValue
doubleValue = (double) intValue //형 맞추기
doubleValue = (double) 10 //변수 값 읽기
doubleValue = 10.0 //형변환
  • 이렇게 앞에 (double)과 같이 적어주면 int 형이 double형으로 형이 변함. 형이 변경되는 것을 형변환이라 한다.
  • 작은 범위 숫자 타입에서 큰 범위 숫자 타입으로의 대입은 개발자가 이렇게 직접 형변환을 하지 않아도 된다. 이런 과정이 자동으로 일어나기 때문에 자동 형변환, 또는 묵시적 형변환이라 한다.

 

형변환 - 명시적 형변환

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

 

Casting2

package casting;

public class Casting2 {

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

        // intValue = doubleValue; // 컴파일 오류 발생
        intValue = (int) doubleValue; // 명시적 형변환
        System.out.println("intValue = " + intValue);
    }
}
  • int 형은 double 형보다 숫자의 표현 범위가 적다. 그리고 실수를 표현할 수 없다. 따라서 숫자가 손실되는 문제가 발생됨. 이런 문제는 매우 큰 버그를 유발할 수 있기 때문에 자바는 컴파일 오류를 발생시킨다.

 

형변환

하지만 만약 이런 위험을 개발자가 직접 감수하고도 값을 대입하고 싶다면 데이터 타입을 강제로 변경할 수 있다.

 

형변환은 변경하고 싶은 데이터 타입을 ( int )와 같이 괄호를 사용해서 명시적으로 입력하면 된다.

intValue = (int) doubleValue; // 형변환

 

이것을 형(타입)을 바꾼다고 해서 형변환(Casting)이라고 하며, 개발자가 직접 형변환 코드를 입력한다고 해서 명시적 형변환이라 한다.

 

 

명시적 형변환 과정

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

 

  • 참고로 형변환을 한다고 해서 doubleValue 자체의 타입이 변경되거나 그 안에 있는 값이 변경되는 것은 아니다. doubleValue에서 읽은 값을 형변환 하는 것임. 변수의 값은 대입연산자( = )를 사용해서 직접 대입할 때만 변경된다.

 

형변환과 오버플로우

 

Casting3

package casting;

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);

        intValue = (int) maxIntOver; // 형변환
        System.out.println("maxIntOver casting = " + intValue);
    }
}

 

출력결과

maxIntValue casting = 2147483647
maxIntOver casting = -2147483648

 

정상 범위 형변환 시 아무런 문제가 없다.

 

초과 범위

int로 표현할 수 있는 가장 큰 숫자보다 1 큰 숫자를 입력했기 대문에 int 범위를 넘어가 마지막에 L을 붙여 long형을 사용해야 함. long int로 표현할 수 있는 범위를 넘기 때문에 형변환 시 문제 발생

  • int 형은 2147483648L를 표현할 수 있는 방법이 없음, 기존 범위를 초과해서 표현하게 되면 전혀 다른 숫자가 표현되는데, 이런 현상을 오버플로우라고 한다.
  • 보통 오버플로우가 발생하면 마치 시계가 한바퀴 돈 것처럼 다시 처음부터 시작됨. maxIntOver의 형변환 결과 값은 int의 가장 작은 숫자임.
  • 오버플로우가 발생했을 때 결과가 어떻게 되는지 계산하는데 시간을 낭비하지 않도록 오버플로우가 발생하지 않게 막아야 함. 위의 경우 대입하는 변수(intValue)의 타입을 int → long으로 변경해서 사이즈를 늘려야 됨.

 

계산과 형변환

Casting4

package casting;

public class Casting4 {

    public static void main(String[] args) {
        int div1 = 3 / 2;
        System.out.println("div1 = " + div1);

        double div2 = 3 / 2;
        System.out.println("div2 = " + div2);

        double div3 = 3.0 / 2;
        System.out.println("div3 = " + div3);

        double div4 = (double) 3 / 2;
        System.out.println("div4 = " + div4);
        
        int a = 3;
        int b = 2;
        double result = (double) a / b;
        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

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

'항해 99 > Java' 카테고리의 다른 글

Java 문법 종합 2주차-2  (0) 2024.01.17
Java 문법 종합 2주차-1  (0) 2024.01.16
Java 문법 종합 1주차  (1) 2024.01.16
Java 기초 2 - 연산자, 조건문  (0) 2024.01.11
Java 기초 - Java, 변수  (0) 2024.01.10