본문 바로가기
개발 노트/오답 노트

구구단 만들기 시 에러 원인

by tokkiC 2022. 4. 13.

자바로 구구단을 만들던 중 생긴 궁금증이었다

단의 입력을 위해 Scanner 클래스를 사용해야 한다고 한다

클래스를 사용하기 위해서는 클래스의 위치를 import 해야하니 아래와 같이 쓰고

import jave.util.Scanner;    // java 하위의 util 하위의 Scanner 를 import 하겠다는 뜻이다

메인 메소드를 통해 인스턴스로 만들어 실행시키기 위해서
메인 메소드 안에 생성자 new를 통해 인스턴스화 한다

public class Gugudan {
    public static void main(String[] args) {
        Scanner dan = new Scanner(System.in);
        }
    }

System.out 은 출력을 돕는 패키지고
System.in 은 입력을 돕는 패키지다

결과의 출력을 위해선 System.out.println();
정수 데이터의 입력을 위해서 System.in.nextInt();

등을 사용하였다

while 반복문을 통해서 1부터 9까지의 곱셈을 연산하려 했으나 여기서 문제가 생겼다

import java.util.Scanner;

public class Gugudan {
    public static void main(String[] args) {
        // 숫자를 입력해서 해당 단의 구구단 실행시키기
        Scanner dan = new Scanner(System.in);

        int dan_number = dan.nextInt();

        System.out.println("구구단 " + dan_number + " 단" );

        int i = 0;

        while (i++<10) {
            System.out.println(dan_number +" 곱하기 "+ i +" 은 " + dan_number * i);

        }
    }
}

숫자 3을 입력하니 콘솔 결과값은 아래와 같았다

3
구구단 3 단
3 곱하기 1 은 3
3 곱하기 2 은 6
3 곱하기 3 은 9
3 곱하기 4 은 12
3 곱하기 5 은 15
3 곱하기 6 은 18
3 곱하기 7 은 21
3 곱하기 8 은 24
3 곱하기 9 은 27
3 곱하기 10 은 30

3 곱하기 10은 필요가 없다. 아니 10까지 곱하는건 계산의도가 아니다

꽤 오래 걸려서야 문제의 원인과 해결방안을 찾았다

문제의 원인은 총 2가지 였다

1. 연산자를 잘못 이해하고 사용하고 있었다


입력은 문제없이 작동했으니 Scanner 클래스를 빼고 문제가 되는 부분으로 코드를 간소화 했다

code 1


public class Gugudan {

public static void main(String[] args) {

int i = 0;

while (i++<3) {
    System.out.println(i);

        }
    }
}

code 2


public class Gugudan {

public static void main(String[] args) {

int i = 0;

while (i<3) {
    System.out.println(i);
    i = i + 1;

        }
    }
}

이 두개가 결과가 같다고 생각하고 사용한게 문제였다

code1 은 while 문의 첫 판단부터 i++ 을 적용하고(i+1이 적용된채로) 비교하여 판단, 시행하였고
while 문 안의 i 값에도 첫 시행부터 i+1 의 값으로 대입하여 시행되었다

하지만 code2 는 while 문의 첫 판단엔 i 의 값(초기값 0) 으로 비교하여 판단, 시행하였고
while 문 안의 i 값은 초기값인 0 부터 시행되었다

다시말해,
code1 은 i++<3 으로 비교하여 참 일때 첫 시행에서 i++ 부터 대입하였고
code2 는 i<3 부터 비교하여 참 일때 첫 시행에서 i 를 대입하였다

code 1 의 결과

     // i++로 메소드 내부를 시행하여 0 의 시행이 없다
1
2
3    // 왜 3이 나왔는지에 대해서는 아래 전위 후위 연산자 부분에서 설명하겠다
code 2 의 결과

0  
1
2

위 처럼 다른 결과를 내는 다른 식 이었다. 꼭 기억하자

2. 반복문에서 전위 연산자와 사후 연사자의 결과는 다를 수 있다


결과 오류의 원인을 찾던 중 연산자의 차이를 알게되었다

++i  // 전위 연산자
i++  // 후위 연산자

code 1의 i++ 을 ++i 로 바꿔도 보았다 // 아래의 code 3

code 3  // 전위 연산자의 경우


public class Gugudan {

public static void main(String[] args) {

int i = 0;

while (++i<3) {
    System.out.println(i);

        }
    }
}

결과값은 아래와 같다

1
2

전위 연산자의 경우 연산을 먼저 한 값을 비교하여 판단, 연산한 값(초기값+1)을 메소드에 대입하여 시행하였다
그 결과 전위 연산자 와 후위 연산자의 결과는 달랐다

결과 값에 
i++ 은 3 포함
++i 는 3 미포함

이는 비교 판단에서 차이가 있는데
간단히 말하자면

i가 연산에 의해 +1 된 값을 a라고 하면 ,

  • 전위 연산자 ++i 를 사용한 경우, 연산 수의 값인 a로 a<3 으로 비교 판단, 연산 후의 값인 a 값으로 메소드를 시행한다

  • 후위 연산자 i++ 를 사용한 경우, 연산 전의 값인 i로 i<3 으로 비교 판단, 연산 후의 값인 a 값으로 메소드를 시행한다

이런 이유로 내가 결과 오류를 냈던 것이었다

어설프게 알면 이처럼 완전 다른 결과값을 내는 다른 식이 낼수있으니 조심하자

댓글