본문 바로가기
개념서/Java

[Java] 조건문, 반복문, 배열

by 사서T 2022. 5. 28.

조건문

   조건문은 조건식과 문장을 포함하는 블럭{}으로 구성되며, 조건식의 결과에 따라 실행흐름이 변경된다. 이때 조건식의 결과는 반드시 boolean형이어야 한다.

if문

   if문의 구조는 다음과 같으며 조건식이 true인 경우 블럭 내의 문장들을 수행한다.

if (조건식) {
    //수행할 문장
}

<블럭의 간단한 특징들>

//1. 블럭의 위치는 {}쌍만 맞으면 어디에 위치하든 상관없지만
//대표적으로 다음 두 가지가 사용된다.
if (조건식) {
    //생략
}

if (조건식)
{
    //생략
}

//2. 블럭 내의 문장이 1개만 있는 경우 블럭을 생략할 수 있다.
if (조건식)
    System.out.println("test");

//3. 블럭이 생략된 경우 문장이 여러 개인 경우
//첫번째 문장을 제외하고 if 외부에 있는 것으로 인식한다.
if (조건식)
    System.out.println("test");   //if 내부
    System.out.println("test1");  //if 내부 x

if-else문

   if문에 else 블럭이 추가된 형태로, if문을 만족하지 않으면 esle문을 실행하게 된다.

if (조건식) {
    //if 조건식이 true인 경우 수행할 문장
} else {
    //if 조건식이 false인 경우 수행할 문장
}

if-else if문

   처리해야 할 경우가 세가지 이상인 경우 사용한다. else if문을 통해 이전 조건식을 만족하지 않는 경우, 다른 조건식으로 연산을 수행한다.

if (조건식1) {
    //조건식1인 true인 경우 수행할 문장
} else if (조건식2) {
    //조건식1이 false이고, 조건식2가 true인 경우 수행할 문장
} else if (조건식3) {
    //조건식2가 false이고, 조건식3이 true인 경우 수행할 문장
} else {
    //else문은 생략될 수 있다.
    //조건식3이 false인 경우 수행할 문장
}

중첩 if문

   if문의 블럭 내에 if문을 포함한 형태이며 횟수 제한은 없다. 중첩이 여러번 있거나 블럭이 생략되는 경우, 블럭의 쌍이 잘 맞는 지 주의해야 하며 들여쓰기를 이용해 중첩 정도를 구분해야 한다.

if (조건식1) {
    if (조건식2) {
        //수행할 문장
    } else {
        //수행할 문장
    }
} else {
    //수행할 문장
}

switch문

   경우의 수가 많아질수록 else-if문이 증가하기 때문에 이를 보완하기위해 switch문을 사용한다. 하지만 switch문은 제약이 많아 경우의 수가 많아도 else-if문을 사용해야 하는 경우가 존재한다.

switch (조건식) {
    case 값1 :
        //조건식의 결과가 값1과 같은 경우 수행할 문장
        break;
    case 값2 : case 값3 :  //값2나 값3 중 하나를 만족하는 경우
        //조건식의 결과가 값2 or 값3과 같은 경우 수행할 문장
        break;
    default :
        //조건식의 결과가 일치하는 case문이 없는 경우 수행할 문장
}

※ break 문이 생략되는 경우 다음 case문을 수행한다.

 

<switch문의 제약조건>

  • switch문의 조건식 결과는 정수 또는 문자열이어야 한다.
  • case문의 값은 정수 상수만 가능하며, 중복되지 않아야 한다.

중첩 switch문

switch (조건식) {
    case 값1 :
        //수행할 문장
        break;
    case 값2 : case 값3 :
        switch (조건식) {
            case 값4 :
                //수행할 문장
                break;
            case 값5 :
                //수행할 문장
                break;
        }
        break;
    default :
        //수행할 문장
}

반복문

for문

   for문은 '초기화', '조건식', '증감식', '블럭'으로 이루어져있으며 조건식이 true인 동안 블럭의 내용을 수행한다. 반복횟수를 알고 있을 때 적합한 구조로 직관적이다. 

//1.형태1
for (초기화; 조건식; 증감식) {
    //수행할 문장
}

//2.형태2 : 우측의 배열 또는 컬렉션의 요소를 하나씩 변수에 초기화하여 사용한다.
for (타입 변수명 : 배열 또는 컬렉션) {
    //수행할 문장
}

//3.형태3 : 수행할 문장이 없는 경우
for (초기화; 조건식; 증감식);
//또는
for (초기화; 조건식; 증감식){}

   for문의 다양한 예제는 다음과 같다.

//i의 초기값은 0, i가 10보다 작을 때까지만 반복을 수행, i를 1씩 증가
for (int i = 0; i < 10; i++) {
    System.out.println("test");
}

//여러 개의 변수를 초기화하는 경우
//이때 두 변수의 타입은 일치해야 한다.
//변수가 여러 개이면 증감식도 여러 개일 수 있다.
for (int i = 0, j = 1; i < 10; i++, j++) {
    System.out.println("test");
}

//형태2를 사용한 경우
int[] arr = {0, 1, 2, 3, 4, 5}
for (int i : arr) {
    System.out.println(i);
}

조건식이 잘못된 경우 블럭의 내용이 무한히 반복되거나, 아예 수행이 안될 수 있다.

 

중첩 for문

   for문도 중첩이 가능하며

for (int i = 0; i < 10; i++) {
    for (int j = 0; j < 10; j++) {
        System.out.println("*");
    }
}

//위와 동일한 코드이며 블록 내의 수행할 문장이 하나이면 블록을 생략할 수 있다.
for (int i = 0; i < 10; i++)
    for (int j = 0; j < 10; j++)
        System.out.println("*");

while문

   while문은 '조건식'과 '블럭'으로 이루어져있으며 조건식이 true일 때까지 블럭의 내용을 수행한다. for문과 마찬가지로 조건식이 잘못된 경우, 블럭의 내용이 무한히 반복되거나 아예 수행되지 않는다.

//while의 조건식은 생략할 수 없다.
while (조건식) {
    //수행할 문장
}

//수행할 문장이 없는 경우
while (조건식);
//또는
while (조건식){}

//아래와 같은 while문은 특수한 for문으로 변경이 가능하다.
while (true) {
    //수행할 문장
}

for (;;) {
    //수행할 문장
}

do-while문

   do-while문은 블럭 내의 내용을 최소한 한 번의 실행을 보장한다. 처음에 실행되는 문장은 조건식의 결과와 상관없이 수행되기 때문에 위험성이 존재한다.

do {
    //수행할 문장
} while (조건식);

break문

   switch문에서 사용된 break와 같은 기능으로 자신이 포함된 가장 가까운 반복문을 벗어난다.

int count = 0;

while (true) {
    count++;
    //count의 값이 10을 초과하면 반복문을 탈출
    if (count > 10)
        break;
}

continue문

   continue문이 수행되면 가장 가까운 반복문의 블럭의 끝으로 이동한다. 즉, 이후 내용을 처리하지 않고 해당 반복문을 다시 수행한다.

for (int i = 0; i < 10; i++) {
    //i가 3의 배수이면 출력을 하지 않는다.
    if (i % 3 == 0)
        continue;
    System.out.println(i);
}

이름 붙은 반복문

   중첩 반복문의 경우 도중에 벗어나기위해 break문을 여러 번 사용해야 한다. 이를 좀 더 효율적으로 하고자 반복문에 이름을 붙이고, break문으로 특정 반복문을 종료하거나, continue문으로 특정 반복문의 블럭 끝으로 이동할 수 있다.

Loop1 : for (int i = 0; i < 10; i++) {
    Loop2 : for (int j = 0; j < 10; j++) {
        if (j == 5) {
            break Loop1;
        } else if (i == 0 && j == 3) {
            continue Loop1;
        }
        System.out.println(i + " " + j);
    }
}

//출력 결과
//0 0
//0 1
//0 2
//1 0
//1 1
//1 2
//1 3
//1 4

배열

   배열은 같은 타입의 여러 변수를 하나의 묶음으로 다루는 것을 의미한다. 선언하는 방법은 두 가지가 존재한다.

 

   다음과 같이 배열을 선언 및 생성할 수 있으며, 예제에선 int형 10개의 메모리 크기만큼 저장공간을 할당한다. 배열의 각 저장공간은 '배열의 요소'라고 하며, '배열이름[인덱스]'의 형태로 배열의 요소에 접근한다. 인덱스는 0부터 배열길이-1 까지의 범위를 가진다.

//타입[] 변수명 = new 타입[길이];
int[] numbers = new int[10];

//인덱스로 배열의 요소 접근
numbers[5] = 10;
System.out.println(numbers[5]);

※ 인덱스의 범위를 벗어나는 요소를 참조하는 경우 에러가 발생한다.

※ 길이가 0인 배열도 생성 가능하다. (ex int[] tmp = new int[0];)

 

   자바에선 JVM이 배열의 길이를 별도로 관리하며, 배열이름.length를 통해 배열의 길이에 대한 정보를 얻을 수 있다.

 

   배열의 길이는 변경이 불가능하기 때문에 배열을 생성할 때 이를 고려해야 한다. 배열이 다 찰때마다 크기를 늘려 기존 내용을 복사하는 경우는 비용이 많이 들고, 처음부터 크게 잡으면 메모리가 낭비될 수 있기 때문이다. 이를 방지하기위해 배열을 생성할 때는 기존 크기보다 2배정도의 크기를 할당하여 사용한다.

 

   만약 배열을 복사해야 하는 경우, System.arraycopy()를 이용하면 효율적인 복사가 가능하다.

 

   다음은 배열을 초기화하는 방법에 대해 생각해보자. 인덱스로 접근하여 배열의 요소를 하나씩 초기화하는 것은 너무 번거롭다.

//1. 반복문을 이용한 초기화
//i의 범위가 배열의 길이까지 포함하는 경우 에러가 발생한다.
for (int i = 0; i < 배열이름.length; i++) {
    배열이름[i] = i;
}

//2. 자바에서 제공하는 방식 : 생성과 동시에 초기화
int[] numbers = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
//new int[] 생략 가능
int[] numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

<알아두기>

※ 그렇다면 선언과 생성, 초기화를 동시에 하는 경우가 아니면 new int[]는 생략할 수 없다. 메서드에 인자로 전달하는 경우도 동일하다.

int[] numbers;

//1. 생성과 초기화 동시에
numbers = new int[]{1, 2, 3, 4, 5};

//2. new int[] 생략
numbers = {1, 2, 3, 4, 5}; //에러

add(new int[]{1, 2, 3, 4, 5}); //정상

add({1, 2, 3, 4, 5}); //에러

참조형 배열의 경우 배열의 요소는 객체의 주소가 저장된다.

String 클래스는 char 배열에 메서드를 추가한 것이다.

//char배열과 String클래스 간의 변환
char[] arr = {'A', 'B', 'C'};
String str = new String(arr);   //char배열을 String클래스로 변환
char[] tmp = str.toCharArray(); //String클래스를 char배열로 변환

다차원 배열

   메모리가 허용되는 한 차원에 제한은 없으며, 차원이 늘어날수록 []가 증가한다.

 

   2차원 배열의 경우 좌측[]가 행, 우측[]가 열이다. 따라서 배열의 요소에는 number[3][2] (number 배열의 3행 2열)와 같이 접근한다. 1차원 배열의 요소는 값을 저장했다면, 2차원 배열의 요소(여기선 행에 저장된 요소를 의미)는 배열의 주소를 가지고 있다.

int[][] number = {{1, 1, 1}, {2, 2, 2}, {3, 3, 3}};
//다음과 같이 전제를 두면
//{1, 1, 1}을 배열 a
//{2, 2, 2}를 배열 b
//{3, 3, 3}을 배열 c
//number[0]에는 a의 주소가 저장
//number[0]에는 b의 주소가 저장
//number[0]에는 c의 주소가 저장

※ 2차원 이상의 배열을 생성할 때 각 요소의 배열 크기를 다르게 생성한 배열을 가변 배열이라고 한다.

int[][] numbers = new int[3][];
numbers[0] = new int[1];
numbers[1] = new int[2];
numbers[2] = new int[3];

Q&A

Q. 배열이란?

A. 같은 타입의 여러 변수를 하나의 묶음으로 다루는 것이다.


참고자료

  • Java의 정석

'개념서 > Java' 카테고리의 다른 글

[Java] 상속  (0) 2022.06.10
[Java] 객체지향 프로그래밍 I  (0) 2022.06.06
[Java] 연산자  (0) 2022.05.27
[Java] 변수  (0) 2022.05.23
[Java] 시작하기  (0) 2022.05.21

댓글