오늘은 자바 프로그래밍 입문 두번째입니다.

어제는 자바가 무엇인지, 자바 스크립트와 어떻게 다른지, 그리고 작동을 어떻게 하는지부터 시작해서 개발환경을 세팅하는 방법을 우선 보았습니다.
그리고 Hello World를 출력해보았고, 자료형과 입출력에 대해 알아보았습니다.

오늘은 Cast와 배열, 조건문에 대해 정리해보겠습니다.

Cast란?


자료형에 대해 복습

우선 우리가 어제 살펴본 자료형에 대해 한 번 더 정리를 할 필요가 있습니다.
숫자 자료형, 문자와 문자열, 논리값인데 표로 한번 나열해보겠습니다!

숫자 자료형

자료형용량우선순위
boolean1byte낮음
byte1byte낮음
short2byte:
int4byte:
long8byte:
float4byte높음
double8byte높음

문자 자료형

자료형용량
char2byte
String글자 개수에 따라 다름

String은 자료형이 아니라 Class이지만 편의상 넣어뒀습니다.

자료형을 변환해보자!

자료형을 변환한다는 말은 이렇게 생각하면 쉬울 것 같습니다!
각 자료형마다 각자 다른 용량을 가지고 있는데, 자료형을 그릇에 비유하고 용량을 그릇의 수용가능 용량이라고 비교해보겠습니다.

그렇다면, 아래와 같이 변수를 선언해 주면 어떻게 될까요?

int num = 23456;
short sh = 12345;
sh = num;

위와 같은 경우에는 에러를 보여주게 될 것입니다. 왜냐하면 short에는 int의 양만큼 채워줄 수가 없기 때문이죠!

그래서 이렇게 쓸 수 있습니다.

int num = 23456;
short sh = 12345;
sh = (short)num;

short 자료 안에 int를 넣는 방법인데 int로 선언된 num을 강제로 short로 바꿔주는겁니다.

이렇게 자료형을 임의로 바꿔주는 것을 우리는 강제 자료형 변환이라고 할 것입니다. 강제 자료형 변환을 Cast라고 합니다.

그리고 또 다음과 같은 예시가 있을 수 있습니다.

int num;
short sh = 12345;

num = short;

이 때는 num의 그릇 크기가 short보다 크기 때문에 short를 채우고도 남습니다. 그래서 굳이 shortint형(16비트 정수형)으로 바꿔주지 않아도 된다는 것이죠!

이렇게 자동으로 자료형이 바뀌는 것을 우리는 자동 자료형 변환이라고 할 것입니다.

또 다른 예시를 보겠습니다.

long l = 123456789L;
float f;

우선 long이라는 범위가 큰 정수형 데이터를 변수 l에 선언해주었습니다.
long을 쓰기 위해서는 반드시 숫자 뒤에 L을 붙여주어야 컴파일러가 int라고 오인하지 않습니다.

자, 그 다음으로

f = l;
System.out.println(f);

를 해주면 어떻게 될까요? 결과는 1.234567892E8이 나올 것입니다.
완전하게 출력되지 않은 것을 알 수 있는데요. 특히 뒤에 보시면 E8이 나와 있는 것을 알 수 있습니다.

E8이 무엇일까요?

double d = 1.234e3;
System.out.println(d);

위와 같은 코드를 실행해보시면 1234.0이 나오는 것을 볼 수 있습니다.
그렇습니다! E는 10을 나타내는 숫자고 뒤에 붙은 수만큼 곱해주는 것입니다.
그러니까 1.234e3에서 e3은 10 10 10의 꼴이 되는 것입니다~~

그러면 d2.34-e2로 하면 어떻게 될까요? 마이너스가 붙으면 소수점을 추가해주면 됩니다. 1/10을 두번 곱하면 되므로 0.0234가 나오겠지요!

그렇다면 Cast는 왜 필요한 것일까요?
예를 들어 다음과 같은 연산이 있다고 가정해봅시다.

int num1, num2;
float fnum;

num1 = 3;
num2 = 2;

fnum = num1 / num2;

System.out.println(fnum);

결과값은 1.0이 출력됩니다. 이상하지요? 3 / 2는 1.5인데 어떻게 1.0이 나오는 것일까요? num1이 정수형이라서 그렇습니다...

이럴 때 Cast를 사용해서 num1의 타입을 바꿔주는겁니다!!

fnum = (float)num1 / num2;
...

이렇게 하시면 1.5가 출력되는 것을 볼 수 있습니다!

Operator: 연산자


사칙연산자

우리가 알고 있는 연산의 종류는 무엇이 있을까요? 바로 사칙연산입니다. 자바에도 사칙연산이 있고, 부수적으로 추가되는 연산이 세가지 정도 있습니다. 표를 통해 알아보겠습니다.

연산자예시의미
+1 + 2 = 3더하기
-2 - 1 = 1빼기
*2 * 2 = 4곱하기
/4 / 2 = 2

여기에 추가로

연산자예시의미
%5 % 2 = 1나머지

가 있습니다.

다음은 사칙연산을 구현하는 방법입니다.

// 임의의 숫자를 담을 변수 선언
int number1, number2;

// 결과값을 담을 변수 선언
int result;

// 임의의 숫자
number1 = 25;
number2 = 3;

// 더하기와 결과값 출력
result = number1 + number2;
System.out.println(result);

// 빼기와 결과값 출력
result = number1 - number2;
System.out.println(result);

// 곱하기와 결과값 출력
result = number1 * number2;
System.out.println(result);

// 나누기 몫과 결과값 출력
result = number1 / number2;
System.out.println(result);

// 나누기 나머지와 결과값 출력
result = number1 % number2;
System.out.println(result);

나눗셈을 할 때는 주의해야 할 사항이 있는데요.
분모가 0이 되어버리면 Exception(예외), 즉 0으로 나눌 수 없다고 나올 것입니다.
컴퓨터에 설치되어 있는 계산기도 어떤 수를 0으로 나누는 계산을 하면 구현하지 못합니다.

자기 자신을 갱신하는 연산자

만약에 0을 초기값으로 갖는 변수가 있다고 했을 때 자기 자신에 1을 더한 값을 출력하려면 어떻게 해야 할까요?

int number = 0;

number = number + 1;

위 코드는 number 변수에 1을 더해서 자기 자신에게 저장해주는 연산을 하는 코드입니다.
이 코드를 조금 더 쉽게 쓰는 법이 있는데요. 다음과 같이 쓸 수 있습니다.

int number = 0;

number += 1;

이렇게 number += 1을 쓰면 number = number + 1과 같은 의미가 됩니다.
더하기, 곱하기, 곱하기, 나누기(몫, 나머지)도 저렇게 사용할 수 있습니다.

increment와 decrement

increment와 decrement는 각각 1증가, 1감소의 의미를 갖습니다.

연산자예시의미
++number++ 또는 ++number1 증가
--number-- 또는 --number1 감소

++은 increment라고 하고 --는 decrement라고 합니다.

예를 들어서,

int number = 0;
number++;
System.out.println(number);

이렇게 작성 하고 출력해주면 number는 1이 되어있을 겁니다. 이제 number가 1이 되어 있으니 num--를 적용해봅시다!

number--;
System.out.println(number);		// -> 0

결과값 0이 확인 되시나요?

이 연산자는 변수명 앞에 붙을 수도 있고 뒤에 붙을수도 있스빈다. 그런데 increment나 decrement한 값을 다른 변수에 저장해서 출력하는 경우 약간의 문제가 발생할 수 있는데요.

어떤 문제가 있을 수 있는지 보겠습니다.

int num1 = 0;
int num2 = 0;

num2 = num1++;

위와 같이 작성할 경우 연산의 우선순위에 의해 num1num2에 대입시킨 후 num1에 1을 증가 시킨 값을 넣어줍니다.
그래서 출력해보시면 num1은 1, num2는 0이 나올 것입니다.

그러면 반대로

num2 = ++num1

을 해주면 어떻게 될까요? 이 때는 num1에 먼저 1을 증가시켜주고 이를 num2에 넣어줍니다. 그래서 num1num2도 모두 1을 반환해줄겁니다.

과제

그렇다면 사칙연산을 바탕으로 과제를 수행해봅시다.

문제 : 편의점에서 물건을 구매합니다. 지불해야 할 금액이 3,210원일 때 10,000원을 낸다면 거스름돈을 얼마 돌려 받을 수 있을까요? 이 때, 거스름돈은 5,000원이 p장, 1000원이 q장, 500원이 s개, 100원이 t개, 50원이 x개, 10원 y개를 받게 됩니다. 받을 거스름돈과 각 금액권 또는 주화별로 몇개를 받는지 구하는 프로그램을 작성해주세요. 단, 지불 해야 할 금액과 제출한 금액은 입출력을 통해 값을 받게 됩니다.

자 우선은 그러면 값을 입력 받기 위해 Scanner라는 모듈이 필요하고 각각의 값을 입력받은 다음 거스름돈을 먼저 구해주는 작업을 해보겠습니다.

// Scanner를 사용하기 위해 모듈 import
import java.util.*;

public class MainClass {
  public static void main(String[] args) {
    
    // 스캐너 모듈 준비
    Scanner scan = new Scanner(System.in);
    
    // 변수 선언
    int price;		// 지불해야 할 금액
    int myMoney;	// 내가 내려는 권종 금액
    int exchange;	// 거스름돈
    
    // 지불해야 할 금액과 내려는 금액을 입력받아 변수에 저장
    System.out.println("지불해야 할 금액은? (숫자만)");
    price = scan.nextInt();
    System.out.println("내가 낸 금액은? (숫자만)");
    myMoney = scan.nextInt();
    
    // 거스름돈 구하기
    exchange = myMoney - price;
  }
}

자 우선은 거스름돈이 잘 출력되는지 System.out.println(exchange);를 입력한 후 출력해줍시다!!

잘 나오나요? 그렇다면 이제 각 권종별로 몇개씩 돌려받는지 작성해줍시다~~

// Scanner를 사용하기 위해 모듈 import
import java.util.*;

public class MainClass {
  public static void main(String[] args) {
    
    ...
    
    // 각 권종별 받을 개수 구하기(exc뒤에 붙는 숫자가 권종명, 예를 들어 exc5000은 거스름돈으로 받을 5000원권의 개수)
    int exc5000 = exchange / 5000;
    int exc1000 = (exchange % 5000) / 1000;
    int exc500 = (exchange % 1000) / 500;
    int exc100 = (exchange % 500) / 100;
    int exc50 = (exchange % 100) / 50;
    int exc10 = (exchange % 50) / 10;
    
    // 그 다음은 이제 출력~~
    System.out.println("거스름돈은 " + exchange + "원 입니다.");
    System.out.println("5000원권은 " + exc5000 + "장 입니다.");
    System.out.println("1000원권은 " + exc1000 + "장 입니다.");
    System.out.println("500원 주화는 " + exc500 + "개 입니다.");
    System.out.println("100원 주화는 " + exc100 + "개 입니다.");
    System.out.println("50원 주화는 " + exc50 + "개 입니다.");
    System.out.println("10원 주화는 " + exc10 + "개 입니다.");
  }
}

완성본입니다!

// Scanner를 사용하기 위해 모듈 import
import java.util.*;

public class MainClass {
  public static void main(String[] args) {
    
    // 스캐너 모듈 준비
    Scanner scan = new Scanner(System.in);
    
    // 변수 선언
    int price;		// 지불해야 할 금액
    int myMoney;	// 내가 내려는 권종 금액
    int exchange;	// 거스름돈
    
    // 지불해야 할 금액과 내려는 금액을 입력받아 변수에 저장
    System.out.println("지불해야 할 금액은? (숫자만)");
    price = scan.nextInt();
    System.out.println("내가 낸 금액은? (숫자만)");
    myMoney = scan.nextInt();
    
    // 거스름돈 구하기
    exchange = myMoney - price;
    
    // 각 권종별 받을 개수 구하기(exc뒤에 붙는 숫자가 권종명, 예를 들어 exc5000은 거스름돈으로 받을 5000원권의 개수)
    int exc5000 = exchange / 5000;
    int exc1000 = (exchange % 5000) / 1000;
    int exc500 = (exchange % 1000) / 500;
    int exc100 = (exchange % 500) / 100;
    int exc50 = (exchange % 100) / 50;
    int exc10 = (exchange % 50) / 10;
    
    // 그 다음은 이제 출력~~
    System.out.println("거스름돈은 " + exchange + "원 입니다.");
    System.out.println("5000원권은 " + exc5000 + "장 입니다.");
    System.out.println("1000원권은 " + exc1000 + "장 입니다.");
    System.out.println("500원 주화는 " + exc500 + "개 입니다.");
    System.out.println("100원 주화는 " + exc100 + "개 입니다.");
    System.out.println("50원 주화는 " + exc50 + "개 입니다.");
    System.out.println("10원 주화는 " + exc10 + "개 입니다.");
  }
}

여기까지 따라오느라 고생하셨습니다!

자 그러면 이제 배열에 대해서 알아보도록 할게요~

Array: 배열


배열이 무엇이고 왜 있는 것일까?

우리가 변수를 선언하는데는 익숙해져 있습니다.
만약에 1년 동안 매일의 기온을 관리하는 리스트를 만들기 위해 변수를 선언한다고 하면 다음과 같이 할 수 있습니다.

int temp1, temp2, temp3, temp4, temp5, ... temp365;

막 그렇게 많아 보이지도 않습니다. 그렇지만 이게 10년치 기록이 쌓이고 20년치 기록이 쌓인다면 그래도 많지 않을까요?

만약 오타로 잘못된 값을 입력했다면 찾아서 수정해줘야 하는데 개수가 많으면 어려울 수 있습니다. 그래서 우리는 배열이라는 녀석을 사용해서 효율적으로 값을 관리할 수 있는 것입니다.

배열은 같은 자료형 변수들의 묶음을 말합니다. 배열의 존재 목적 자체가 변수의 효율적인 관리이고 배열 안에 있는 변수들은 indexNumber 즉, 각 값의 주소로 찾고 편집할 수 있습니다.

배열은 이렇게 생겼습니다.

자료형 배열변수명[] = new 자료형[배열 원소의 총 개수];

이렇게 new를 써서 배열을 만들어 주는 방법이 일단 있는데, 여기에 동적으로 값을 할당해줄 수 있습니다.

무슨 말인지 잘 모르겠으니 한번 만들어봅시다!

배열을 만들어보자!

4바이트 정수형으로 동적 할당이 가능한 배열을 만들어주겠습니다.

int myArray[] = new int [5];

여기에는 다섯개의 원소들이 들어갈 수 있고 각 원소는 배열이름과 주소로 할당할 수 있습니다.

int myArray[] = new int [5];

myArray[0] = 11;
myArray[1] = 22;
myArray[2] = 33;
myArray[3] = 44;
myArray[4] = 55;

이러한 배열의 형태를 동적 할당이 가능한 배열이라고 합니다.
중요한 사실은 배열의 index는 0부터 시작한다는 사실을 잊지 마세요!

형태를 다르게 쓸 수도 있습니다.

int myArray[] = new int [5];
int []myArray = new int [5];
int[] myArray = new int [5];

세 가지 형태를 모두 다 취할 수 있습니다. 그리고 배열에서 값을 추출할 때에는 출력 메서드에 배열이름(배열 인덱스)를 입력해주면 됩니다.

int myArray[] = new int [5];

myArray[0] = 11;
myArray[1] = 22;
myArray[2] = 33;
myArray[3] = 44;
myArray[4] = 55;

System.out.println(myArray[2]);		// -> 33

전체를 다 조회하기 위해서는 Arrays.toString() 메서드를 사용합니다.

System.out.println(Arrays.toString(myArray);
// -> [11, 22, 33, 44, 55]

이렇게 하면 배열을 전부 문자열화 하여 배열 그대로를 반환해줍니다.

배열에 아예 고정된 값을 선언해 줄 수도 있습니다.
그 때는 자료형 배열이름[] = { 원소들 };과 같은 형태로 써 줄 수 있습니다.

int myArray[] = { 11, 22, 33, 44, 55 };

// 특정 인덱스의 값도 같은 방식으로 출력합니다.
System.out.println(myArray[4]);		// -> 55

그럼 문자 배열을 만들어봅시다.

char chArray[] = { 'h', 'e', 'l', 'l', 'o' };

이 배열은 자료형으로 char을 써주어 문자 하나씩을 원소로 갖는 배열입니다.

여기서는 이 배열의 길이도 한 번 구해보겠습니다. 배열의 길이는 .length를 써서 확인합니다. 그리고 배열의 원소들을 Arrays.toString()메서드로 출력해 보겠습니다.

System.out.println(chArray.length);		// -> 5
System.out.println(Arrays.toString(chArray));	// -> Hello

원소가 다섯개이므로 5라는 값을 출력해 줄 것입니다.
그리고 char 자료형을 갖는 배열은 Arrays.toString() 메서드로 출력할 때 하나의 문자열로 반환해줍니다.

다음 예제를 보겠습니다.

char c = 'A';
System.out.println(c);		// -> A
System.out.println((int)c);	// -> 65

char 자료형으로 알파벳 대문자 A를 선언하고 이것을 변수 c에 담았습니다.
c를 그대로 출력하면 알파벳 A가 나오지만 자료형을 강제로 int형으로 바꿨을 때는 ASCII 코드가 반환됩니다. 아스키 코드는 숫자와 영문자를 컴퓨터에서 해석하는 방식입니다. ASCII 코드에 대해 검색해보세요.

String으로 선언해주는 배열도 있습니다.
char는 한글자씩 밖에 원소로 받지 못하기 때문에 문장을 배열의 각 인덱스가 참조하게 하려면 String으로 만들어주시면 됩니다.

String myStrArr[] = { "Hello", "World", "This is Java" };

이렇게 두글자 이상의 단어나 문장을 넣어줄 수 있는 배열이 완성되었습니다!! 인덱스별 원소를 찾는 방법도 intchar와 동일합니다.

자 그러면 각각의 배열 자체와 Arrays.toString() 메서드를 사용하여 콘솔에 출력해 보겠습니다.

실습

int myIntArr[] = new int [5];

myIntArr[0] = 11;
myIntArr[1] = 22;
myIntArr[2] = 33;
myIntArr[3] = 44;
myIntArr[4] = 55;

System.out.println(myIntArr);		// -> [I@6d06d69c
System.out.println(Arrays.toString(myIntArr)); // -> [11, 22, 33, 44, 55]

///////////////////////////////////////////////

char myChArr[] = { 'H', 'e', 'l', 'l', 'o' };

System.out.println(myChArr);		// -> Hello
System.out.println(Arrays.toString(myChArr)); // -> [H, e, l, l, o]

///////////////////////////////////////////////

String myStrArr[] = { "Hello", "World", "This is Java" };
		
System.out.println(myStrArr);		// -> [Ljava.lang.String;@7852e922
System.out.println(Arrays.toString(myStrArr)); // -> [Hello, World, This is Java]

보시면 두개의 출력결과가 좀 이상하다는 것을 알 수 있습니다.
알 수 없는 문자들이 나열되어 있지요? 이것은 Heap 주소인데, Heap이 무엇인지에 대해서 이 포스팅 마지막에 자세히 다뤄보겠습니다.

2차원 배열이란?

우리가 앞에서 살펴본 배열은 데이터가 한줄로만 입력되는 1차원 배열입니다.
0-0-0-0-0-0-0 이런식으로 배열이 연결되어있죠!

그렇지만 아래처럼 연결된 구조가 충분히 있을 수 있습니다!
0-0-0-0-0
0-0-0-0-0
0-0-0-0-0

이렇게 연결된 배열을 2차원 배열이라고 하고, 이 데이터는 행과 열을 갖습니다.
그에 반해 1차원 배열은 행으로만 이루어져 있는 배열이지요!

2차원 배열은 어떻게 만드는가??

1차원 배열에서는 int arr[] = new int[3]처럼 선언했습니다. 자료가 행만 있기 때문에 대괄호를 하나만 써줬습니다.

2차원 배열은 행과 열로 이루어져있기 때문에 1차원배열에 괄호를 하나 더 붙여주면 됩니다!

int array[][] = new int[3][4];
int []array[] = new int[3][4];
int [][]array = new int[3][4];

마찬지로 어느 형태로 쓰더라도 상관이 없습니다!

또한 동적할당이 아닌 아예 값을 고정해 줄 수 있는 형태를 1차원 배열과 마찬가지로 취할 수 있습니다.

int array2[][] = {
  { 1, 2, 3, 4 },
  { 5, 6, 7, 8 },
  { 9, 10, 11, 12}
}

이 배열 또한 인덱스는 0부터 시작하는데 행과 열의 구조로 되어있으므로 인덱스는(0, 0)으로 시작합니다.

그래서 만약 Array3이라는 변수를 갖는 2차원 배열에
1-2-3-4
5-6-7-8
9-10-11-12
를 동적으로 할당하는 배열을 만든다면 다음과 같이 할 수 있습니다.

int Array2[][] = new int[3][4];
		
Array2[0][0] = 1;
Array2[0][1] = 2;
Array2[0][2] = 3;
Array2[0][3] = 4;
		
Array2[1][0] = 5;
Array2[1][1] = 6;
Array2[1][2] = 7;
Array2[1][3] = 8;
		
Array2[2][0] = 9;
Array2[2][1] = 10;
Array2[2][2] = 11;
Array2[2][3] = 12;

이렇게 만들어진 배열에서 값을 추출해 보겠습니다.

System.out.println(Arrays.toString(Array2[0]));

위와 같이 작성하면 0번 인덱스를 조회하는데 앞서 살펴본 것처럼 2차원 배열은 행과 열을 갖기 때문에 행만 참조하여 알려줄 것입니다.
그래서 결과적으로 [1, 2, 3, 4]를 반환해 줄 것입니다.

조건문

조건문은 말 그대로 주어진 조건에 대해 참거짓을 판별하여 표현식을 처리해주는 형태를 말합니다.

예를 들면 점수를 입력하면 성적을 출력해주는 시스템을 들 수가 있겠네요.

그렇다면 조건문에는 어떤 종류가 있을까요?

if 조건문

if 조건문은 주어진 조건을 판별하여 처리문을 처리해주는 문장을 말합니다.

기본적인 형태는 이렇습니다.

if (조건) { 조건의 true / false를 판별하여 처리 }

예를 들어 조건이 a가 10이면 "a가 10입니다"를 출력하는 프로그램을 작성하면

int a = 10;
if (a == 10) {
  System.out.println("a가 10입니다");
}

가 됩니다. 주어진 조건과 맞지 않는다면 어떠한 것도 실행하지 않습니다.

그러면 a가 10이 아닐 때 "a가 10이 아닙니다"를 출력하려면 어떻게 할까요?

if else

이 때는 if else문을 사용해서 조건이 참일 때는 어떤 것을 처리하고 참이 아닐 때는 다른걸 실행하게 할 수 있습니다.

// 기본적인 형태
// if (조건) { 조건을 판별하여 처리 } else { 조건이 참이 아니면 처리 }

if (a == 10) {
  System.out.println("a가 10입니다");
} else {
  System.out.println("a가 10이 아닙니다");
}

조건을 분기할 수도 있는데요, 예를 들어 score가 100점이면 A+, 95점 이상이면 A, 90점이면 B+, 그 이하면 B를 출력한다고 가정해봅시다.

if else if

이렇게 조건의 분기가 필요할 때 if else if문을 사용해주면 됩니다.

int score = 97;

if (score == 100) {
  System.out.println("A+");
} else if (score >= 95) {
  System.out.println("A");
} else if (score >= 90) {
  System.out.println("B+");
} else {
  System.out.println("B");
}

그 이하면 "B"라는 조건이 필요하지 않다면 굳이 else는 작성하지 않아도 됩니다!!

이렇게 다양한 조건을 부여하여 if문을 작성할 수 있습니다!!

여기서 잠깐!
비교 연산자가 무엇인지 알고 계신가요? 비교 연산자는 말 그대로 값을 비교하기 위한 연산자 입니다. 종류만 빠르게 살펴보고 가겠습니다.

연산자의미
==같다
>크다
<작다
>=크거나 같다
<=작거나 같다
!=다르다
int a = 1;
int b = 2;

boolean c = false;

// a == 1이 참이므로 "a가 1입니다."라는 문장이 출력됩니다.
if (a == 1) {
  System.out.println("a가 1입니다.");
}

// a == b는 거짓이므로 else에 있는 문장이 출력됩니다.
if (a == b) {
  System.out.println("a와 b는 같습니다");
} else {
  System.out.println("a와 b는 같지 않습니다.);
}

// a가 b보다 작거나 같으므로 if 블럭 내부의 문장이 실행됩니다.
if (a <= b) {
  System.out.println("a는 b보다 작거나 같습니다");
} else {
  System.out.println("a는 b보다 크거나 같습니다");
}

// c는 false로 선언되었으므로 else 블록 내부에 있는 문장이 실행됩니다.
if (c) {
  System.out.println("true입니다.");
} else {
  System.out.println("false입니다");
}

// c를 부정하게 되면 true가 되므로 if 블록 내부에 있는 문장이 실행됩니다.
if (!c) {
  System.out.println("true입니다.");
} else {
  System.out.println("false입니다");
}

순환문

switch case

앞서 살펴본 if else if문은 조건을 분기하는데 사용했으며 값의 범위도 비교할 수 있었습니다.

이와 비슷한 개념의 순환문으로 switch case문이 있습니다. 주어진 조건(switch)과 값(case)을 비교하여 결과를 출력해 줄 수 있습니다.

if else if문에서는 어떤 숫자가 크거나 같다 등의 비교 연산자를 사용할 수 있었는데 switch case문은 정해진 값만으로 즉 명확히 지정된 값만으로 비교해 줄 수 있다는 특징이 있습니다. 그리고 float 형태의 자료형을 사용할 수 없습니다!

마지막에 default 값을 넣어주는데, default는 조건과 일치하는 것이 아무것도 없을 때 반환해 줄 내용을 넣습니다.

그리고 각 case마다 break를 입력해줘야 하는데 입력해주지 않으면 계속적으로 다른 조건들을 순환하게 됩니다.

int number = 2;
		
switch (number) {
  case 1:
    System.out.println("number is 1");
    break;
  case 2:
    System.out.println("number is 2");
    break;
  case 3:
    System.out.println("number is 3");
    break;
  /*
  범위 사용 불가
  case number > 8:
    System.out.println("number is 9");
    break;
  */
  // default는 생략이 가능하다!!
  default:
    System.out.println("number is " + number);
    break;

자, 그러면 이제까지 정리한 내용을 바탕으로 과제를 수행해보겠습니다.

과제

문제: 정수 p와 q, 연산자를 입력받아 p연산q의 결과를 만들어주는 계산기 프로그램을 작성해주세요!

프로그램을 작성하기 전에 어떤 요소가 들어가야 할 지 먼저 기록해둡시다!

  1. 정수 p입력 받기
  2. 연산자 입력 받기
  3. 정수 q입력 받기
  4. 연산자에 해당하는 계산 결과 도출하기

스캐너를 사용해서 입력 받은 1, 3의 값을 저장해주고,
저는 switch case를 사용해서 연산 결과를 도출해주겠습니다.

import java.util.*;

public class MainClass {

  public static void main(String[] args) {
		
    // 계산기를 만들어보자!
    
    // 값을 입력받기 위해 필요한 모듈
    Scanner scan = new Scanner(System.in);
    
    // 1번째 숫자 입력받기
    System.out.print("첫번째 숫자를 입력하세요 : ");
    int firstNum = scan.nextInt();
    
    // 연산자 입력 받기
    System.out.print("연산자를 입력해주세요 : ");
    String operator = scan.next();
    
    // 두번째 숫자 입력 받기
    System.out.print("두번째 숫자를 입력하세요 : ");
    int secondNum = scan.nextInt();
    
    // 입력받은 연산자에 따라 결과값 다르게 지정하기
    int answer = 0;
    switch (operator) {
      case "+":
        answer = firstNum + secondNum;
        break;
      case "-":
        answer = firstNum - secondNum;
        break;
      case "*":
        answer = firstNum * secondNum;
        break;
      case "/":
        answer = firstNum / secondNum;
        break;
      default:
        System.out.println("잘못된 연산자를 입력하였습니다!");
        break;
      }
    // 연산결과 출력하기
    System.out.println(firstNum + operator + secondNum + "=" + answer);
    
  }
}

여기까지 따라오느라 고생 많으셨습니다! 자 오늘 준비한 내용은 여기까지입니다. 더욱 재미있는 내용이 부록에서 기다리고 있습니다.

부록


Stack, Static, Heap, System이란?

업로드 예정

equals() 비교 함수

가령 아래와 같은 소스코드가 있다고 가정해봅시다.

String str1 = "안녕하세요";
String str2 = "안녕";

// str2를 기존의 str2(안녕)에 문자열 '하세요'를 붙인 값을 더해줍니다.
str2 += "하세요";

System.out.println(str2);	// -> 안녕하세요

if (str1 == str2) {
  System.out.println("같은 문자열 입니다.");
} else {
  System.out.println("다른 문자열 입니다.");
}

이 때는 다른 문자열이라는 메시지가 출력될 것입니다!

왜냐하면 str1은 "안녕하세요"라는 문자 자체를 담고 있지만 ==이라는 비교 연산자는 객체를 비교하지 객체가 가진 문자열을 비교하진 않습니다. 비교하려는 객체가 같은 주소를 참조하고 있는지 여부를 검토합니다.
그래서 str1str2는 값은 같지만 서로 다른 객체이기 때문에 false가 되는 것입니다.

추가적으로 기존의 str2str2 += "하세요"str2를 변경한 값의 주소도 달라질 수 있습니다. 자바에서 String의 값을 변경하게 되면 heap 메모리에 새로운 주소를 얻어서 새로운 주소에 객체를 할당하고 이전에 썼던 메모리 주소는 더이상 사용하지 않게 되어 가비지 컬렉터가 정리해줍니다.

다른 객체의 값을 비교하기 위해 우리는 equals() 메서드를 사용할 수 있습니다.

그래서,

String str1 = "안녕하세요";
String str2 = "안녕";

str2 += "하세요";

System.out.println(str2);

if (str1.equals(str2)) {
  System.out.println("같은 문자열 입니다.");
} else {
  System.out.println("다른 문자열 입니다.");
}

이렇게 str1.equals(str2)로 해주게 되면 값이 같은지를 비교해줍니다!

profile
tried ? drinkCoffee : keepGoing;

0개의 댓글