Java 언어과제

서병범·2022년 9월 23일

항해99

목록 보기
3/4

[항해99 9기] 프로그래밍 기초주차 주특기 과제 제출

문제공통)

문제 1번)

답)

public class Homework1 {

    public static void main(String[] args) {
        int var1=5;
        int var2=2;
        double var3=var1/var2;
//        =>  double var3=5/2;
        System.out.println(var3);
//        Java에서 정수끼리의 산술 연산 결과는 정수 값이기 때문에, 실제로는 5/2=2.5 이어도 2로 계산이 된다.
//        하지만 선언되는 변수(double)의 타입이 실수이기 때문에, 2는 2.0으로 출력된다.

        int var4=(int)(var3*var2);
//        =>  int var4=(int)(2.0*2);
//        2.0*2이지만, 정수 출력이기 때문에 4로 나온다.
//        추가로 알 수 있는것: 선언되는 변수(double)의 타입이 실수여도, (int)정수를 포함한 계산이 실행된다.        
        System.out.println(var4);
    }
}

해설

왜 답이 저렇게 나왔을까에 대해 고민하던 중,
일단 마구잡이로 해보면서 알아내는게 제일 쉬울 것 같다는 생각을 했다.

int var3=var1/var2; : 2
double var4=(int)(var3*var2); : 4.0
=> double var4=(int)(2*2); : 4.0
double var4=(double)(var3*var2); : 4.0
=> double var4=(double)(2.0*2.0); : 4.0

결국 선언되는 변수의 자료형(Data Type)에 따라 값이 정해진다.

int var4=(double)(var3*var2); 
// 오류) java: incompatible types: possible lossy conversion from double to int
==> double 을 int로 바꾸라고 나온다.
	Java에서의 변수는 값의 형태에 맞는 자료형을 지정해주어야 한다.
double var4=(int)(var1*var2); : 10.0
// => double var4=(int)(5*2); : 10.0
==> (int)정수끼리의 계산이여도 (double)실수로 출력
double var4=(double)(var1*var2); : 10.0
// => double var4=(double)(5*2); : 10.0
==> 계산 실행된다.

문제 2번)

public class Homework2 {
    public static void main(String[] args) {
        int x=10;
        int y=20;
        System.out.println(++x);
//      => 11
        System.out.println(y--);
//      => 20

        int z = (++x) + (y--);
        System.out.println(z);
//      => 31
    }
}

이유

컴파일러 시, 컴퓨터는 왼쪽에서 오른쪽으로 읽어 나간다.
그렇기 때문에 number++는 출력된 뒤에 값이 증가하고
++number는 증가하고 값이 출력된다.
이것을 후위증감연산자전위증감연산자라고 한다.
이 두 가지의 차이는 Java 뿐만 아니라 C, C++ 등 다른 언어에서도 같다.

예시로,

    public static void main(String[] args) {
        int number = 1;
        System.out.println(++number);
        System.out.println(number++);
    }
}
값
2   =>  ++되어서 2가 출력되고,
2   =>  그대로 number가 출력된 뒤, 값이 증가한다.
    public static void main(String[] args) {
        int number = 1;
        System.out.println(number++);
        System.out.println(++number);
    }
}
값
1   =>  출력되고난 뒤, 값이 증가해서 number : 2가 되고
3   =>  값이 2에서 ++되어서 3이 되어 출력된다.
  

문제 3번)

public class Homework3 {

    public static void main(String[] args) {
        // 2개의 주사위를 던졌을 때 나오는 눈의 합이 5눈의 합이 5이면 실행을 멈추기

        System.out.println("시작!");
        while (true) {
            int dice1 = (int) (Math.random() * 6) + 1;
            int dice2 = (int) (Math.random() * 6) + 1;
//          조건) 주사위는 1~6까지의 정수여야한다.
//          Math.random()은 double date type을 가진다. => (int)를 이용해 정수로 만들어야한다.
//          Math.random()은 0~1사이의 랜덤한 값을 출력해낸다. => 정수로 만들면 0의 값을 가진다.
//          주사위는 1부터 시작하기 때문에 Math.random()뒤에 +1을 해줘서 1이상의 값을 내도록 한다.
//          (Math.random() * 100) 과 같이 뒤에 원하는 범위의 숫자를 적어준다.(Math.random()자체를 1로 생각)
//          While 반복문은 (..)안의 조건이 true 경우 {..} 내부의 소스를 실행
//          (true)일 시, 무한루프 진행
//
            if ((dice1 + dice2) != 5)
                System.out.println("("+dice1+","+dice2+")");
//          if 조건이 false인 경우, else {}블록내의 소스를 실행한다.
            else {
                System.out.println("("+dice1+","+dice2+")");
                System.out.println("끝!");
                break;
//          무한루프를 걸어줬기 때문에, break로 while문 탈출
            }
        }
    }
}

트러블 슈팅

첫번째,

처음 설계할 때,
만약 주사위 합이 5라면 값을 출력하고 끝,
아니라면, 반복해서 값을 출력이라고 생각해서, 아래와 같이 코드를 짰다.

 if ((dice1 + dice2) == 5)
        System.out.println("(" + dice1 + "," + dice2 + ")");
        System.out.println("끝!");
        else {
            while((dice1 + dice2) != 5)
            System.out.println("(" + dice1 + "," + dice2 + ")");
        }

근데 이런 식으로 코드를 짜고나니 dice를 어디에서 설정하든, 알고리즘이 도저히 굴러가지 않았다.
그래서 while문 안에 if를 넣기로 했다.

두번째,

Math.random()while문 위에서 먼저 설정하고 시작하니,
처음 뽑은 수가 똑같이 계속 출력되었다.
while(..){..} 반복문은
(..)조건이 false일 경우, {..}안에서 돌기때문에,
Math.random()while문 안으로 넣어줘야 계속 주사위를 다시 굴릴 수 있다는 걸 깨달았다.

세번째,

while(..){}에서 (..)안에 조건을 걸어줘야하는데, 뭐를 넣어야할 지 감이 안왔다.
그래서 구글링을 하던 중에, 무한루프를 만들어주는 법을 알아냈다.
무한 루프를 만드는 방법은 다음과 같다.

while에 조건식 대신 true를 지정하면 무한히 반복하는 무한 루프가 만들어집니다.
조건식이 항상 참(true)이므로, 따라서 변화식도 필요 없습니다.

그 외에도, 0이 아닌 숫자는 True로 취급하여 무한 루프로 동작

while 1:    # 0이 아닌 숫자는 True로 취급하여 무한 루프로 동작
    print('Hello, world!')

내용이 있는 문자열은 True로 취급하여 무한 루프로 동작

while 'Hello':    # 내용이 있는 문자열은 True로 취급하여 무한 루프로 동작
    print('Hello, world!')

마지막으로,
무한 루프에서 빠져나오는 방법은 break; 를 걸어주면 된다.
출처)https://dojang.io/mod/page/view.php?id=2249


추가로 알게된 것

println vs printf

println()

System.out.println("문자열");
또는
System.out.println(변수명);
또는
System.out.println("문자열"+변수명);

  • 문자열을 출력하기 위해서는 ""로 묶어줘야 한다.
  • "" 없는 것은 모두 변수명으로 인식한다.
  • 문자열과 변수명을 함께 사용할 수 있으나 반드시 '+'로 연결시켜줘야 한다.
  • (..)안의 내용을 출력한 후 자동으로 줄바꾸는 기능이 있다.

printf()

System.out.printf("출력 서식",출력할 내용);

  • 출력 후 줄바꿈을 하지 않는다. 줄바꿈을 하려면 지시자 '%n'을 넣어줘야 한다.
  • 출력하려는 값의 수만큼 지시자도 사용해야 한다.
  • 출력될 값과 지시자의 순서는 일치해야 한다.
  • 지시자를 제외한 문자는 입력한 그대로 출력된다.

example)

public class Printf {
 
    public static void main(String[] args) {
        
        int age = 10;        
        String addr = "경기도";
        
        //'%n'지시자를 사용 안 했을 경우
        System.out.printf("줄바꿈 기능");
        System.out.printf("없음.");
        
        //'%n'지시자를 사용한 경우
        System.out.printf("줄바꾸기%n");
        System.out.printf("성공!%n");
        
        System.out.printf("내 나이는 %d살 입니다.%n",age);
        System.out.printf("내 나이는 %d살 이고 %s에 살고 있습니다.%n",age,addr);
        
    }//main
 
}//class

출력결과)

줄바꾸기 기능없음.줄바꾸기

성공!

내 나이는 10살 입니다.

내 나이는 10살이고 경기도에 살고 있습니다.

마지막 출력문구

System.out.printf("내 나이는 %d살 이고 %s에 살고 있습니다.%n",age,addr);

에서 볼 수 있듯이,
%n을 제외한,
지시자(%d, %s)와 대응되는 값(age, addr)의 순서는 같다. 그리고 지시자(2개)와 값(2개)의 개수도 같다.

대표적인 printf() 지시자 종류

이걸 이용해서, 마지막 3번 문제를 다시 풀어보자

public class Homework4 {

    public static void main(String[] args) {
        // 2개의 주사위를 던졌을 때 나오는 눈의 합이 5눈의 합이 5이면 실행을 멈추기

        System.out.println("시작!");
        while (true) {
            int dice1 = (int) (Math.random() * 6) + 1;
            int dice2 = (int) (Math.random() * 6) + 1;
//          조건) 주사위는 1~6까지의 정수여야한다.
//          Math.random()은 double date type을 가진다. => (int)를 이용해 정수로 만들어야한다.
//          Math.random()은 0~1사이의 랜덤한 값을 출력해낸다. => 정수로 만들면 0의 값을 가진다.
//          주사위는 1부터 시작하기 때문에 Math.random()뒤에 +1을 해줘서 1이상의 값을 내도록 한다.
//          (Math.random() * 100) 과 같이 뒤에 원하는 범위의 숫자를 적어준다.(Math.random()자체를 1로 생각)
//          While 반복문은 (..)안의 조건이 true 경우 {..} 내부의 소스를 실행
//          (true)일 시, 무한루프 진행
//
            if ((dice1 + dice2) != 5) {
                System.out.printf("(%d,%d)%n", dice1,dice2);
//                System.out.println("("+dice1+","+dice2+")");
            }
//          if 조건이 false인 경우, else {}블록내의 소스를 실행한다.
            else {
                System.out.printf("(%d,%d)%n", dice1,dice2);
//                System.out.println("("+dice1+","+dice2+")");
                System.out.println("끝!");
                break;
//          무한루프를 걸어줬기 때문에, break로 while문 탈출
            }
        }
    }
}

값이 잘 나오는 걸 볼 수 있다.


살짝 회고를 하자면,
3번 문제를 출력하면서, 안그래도 ( , ) 꼴을 너무 1차원적으로 출력하는 것 같다고 생각 했는데,
같은 조원의 결과물을 보고 printf() 방법을 알게 되었다.
그래서 printf()를 사용해봤는데, 결과값이 가로로 배열되는 걸 알 수 있었다.
모든 과제를 하면서, 결과값이 세로로 배열되는 것에 대해서 특별히 인지하고 있지 않았기 때문에 해결방법을 몰랐다.
그래서 구글링을 통해 printf()의 특징을 알아보았고, 그 결과 %n을 추가해서 해결했다.

같은 조끼리 각자의 답을 공유해서 비교해보는 것이 중요하는 걸 느꼈다.👍

profile
코딩초보

0개의 댓글