반복문과 배열 그리고 예외처리
1. 반복문
1) for 문
가장 많이 사용하는 반복문
//반복후 작업문에 콤마로 분리하여 2 문장 작성가능
for(int i = 0; i < 10; System.out.println(i), i++) {
System.out.println(i);
}
for(int i = 0; i < 10; i++)
System.out.print(i);
// 무한반복
for(초기문; true; 반복 후 작업) {
...........
}
// 무한 반복
for(초기문; ; 반복 후 작업) {
...........
}
public class ForSample {
public static void main(String[] args) {
int i, sum = 0;
for(i = 1; i <= 10; i++) { // 1~10까지 반복
sum += i;
System.out.print(i); // 더하는 수 출력
if(i <= 9) // 1~9까지는 '+' 출력
System.out.print("+");
else { // i가 10인 경우
System.out.print("="); // '=' 출력하고
System.out.print(sum); // 덧셈 결과 출력
}
}
}
}
2) while 문
조건식이 ‘참’인 동안 반복 실행
0123456789
import java.util.Scanner;
public class WhileSample {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int count = 0, n = 0;
double sum = 0;
System.out.println("정수를 입력하고 마지막에 0을 입력하세요.");
while((n = scanner.nextInt()) != 0) { // 0이 입력되면 while 문 벗어남
sum = sum + n;
count++;
}
System.out.print("수의 개수는 " + count + "개이며 ");
System.out.println("평균은 " + sum/count + "입니다.");
scanner.close(); }
}
3) do-while 문
조건식이 ‘참’인 동안 반복 실행 작업문은 한 번 반드시 실행
public class DoWhileSample {
public static void main (String[] args) {
char a = 'a';
do {
System.out.print(a);
a = (char) (a + 1);
} while (a <= 'z');
// abcdefghijklmnopqrstuvwxyz
}
4) 중첩 반복
반복문이 다른 반복문을 내포하는 구조
for(int i = 0; i < 100; i++) { // 100개 학교 성적을 더한다.
for (int j = 0; j < 10000; j++) { // 10000명의 학생 성적을 더한다.
...
...
}
...
}
10000명의 학생이 있는 100개 대학의 모든 학생 성적의 합을 구할 때, for 문을 이용한 이중 중첩 구조
public class NestedLoop {
public static void main(String[] args) {
for(int i = 1; i < 10; i++) { // 단에 대한 반복. 1단에서 9단
for(int j = 1; j < 10; j++) { // 각 단의 곱셈
System.out.print(i + "*" + j + "=" + i*j); // 구구셈 출력
System.out.print('\t'); // 하나씩 탭으로 띄기
}
System.out.println(); // 한 단이 끝나면 다음 줄로 커서 이동
}
}
}
5) continue 문
반복문을 빠져 나가지 않고, 다음 반복으로 제어 변경 반복문에서 continue; 문에 의한 분기
import java.util.Scanner;
public class ContinueExample {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("정수를 5개 입력하세요.");
int sum = 0;
for(int i = 0; i < 5; i++) {
int n = scanner.nextInt();
if(n <=0 )
continue; // 0이나 음수인 경우 더하지 않고 다음 반복으로 진행
else sum += n; // 양수인 경우 덧셈
}
System.out.println("양수의 합은 " + sum);
scanner.close();
}
}
정수를 5개 입력하세요.
5 -2 6 10 -4
양수의 합은 21
6 break 문
하나의 반복문만 벗어남
중첩 반복의 경우 안쪽 반복문의 break 문이 실행되면 안쪽 반복문만 벗어남
import java.util.Scanner;
public class BreakExample {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("exit을 입력하면 종료합니다.");
while(true) {
System.out.print(">>");
String text = scanner.nextLine();
if(text.equals("exit")) // "exit"이 입력되면 반복 종료
break; // while 문을 벗어남
System.out.println("종료합니다...");
scanner.close();
}
}
}
exit을 입력하면 종료합니다.
>>edit
>>exit
종료합니다...
2. 배열
1) 자바배열
- 인덱스와 인덱스에 대응하는 데이터들로 이루어진 자료 구조
- 배열을이용하면한번에많은메모리공간선언가능
- 배열은 같은 타입의 데이터들이 순차적으로 저장되는 공간
- 원소 데이터들이 순차적으로 저장됨
- 인덱스를 이용하여 원소 데이터 접근
- 반복문을 이용하여 처리하기에 적합한 자료 구조
- 배열 인덱스
- 0부터시작
- 인덱스는 배열의 시작 위치에서부터 데이터가 있는 상대 위치
2) 자바 배열의 필요성과 모양
- 10개의 정수형 변수를 선언하는 경우
-
10개의 정수로 구성된 배열을 선언하는 경우
3) 배열 선언 및 생성
-
배열에 대한 래퍼런스 변수 intArray 선언
-
배열
배열 선언 : 배열의 이름 선언(배열 레퍼런스 변수 선언)
배열 생성: 배열 공간 할당 받는 과정
배열 초기화 : 배열 생성과 값 초기화
intintArray[] = {4, 3, 2, 1, 0}; //5개의정수배열생성및값초기화
double doubleArray[] = {0.01, 0.02, 0.03, 0.04}; // 5개의 실수 배열 생성 및 값 초기화
4) 배열을 초기화하면서 생성한 결과
별다른 내용 없어 생략
5) 배열 인덱스와 배열 원소 접근
-
배열의인덱스는0~ (배열크기–1)
-
인덱스를 잘못 사용한 경우
-
반드시 배열 생성 후 접근
6) 레퍼런스 치환과 배열 공유
레퍼런스 치환으로 두 레퍼런스가 하나의 배열 공유
int intArray[] = new int[5];
int myArray[] = intArray; // 레퍼런스 치환으로 배열 공유
intArray[1] = 6;
myArray[1] = 6;
7) 배열 선언 및 생성
import java.util.Scanner;
public class ArrayAccess {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int intArray[];
intArray = new int[5];
int max = 0; // 현재 가장 큰 수
System.out.println("양수 5개를 입력하세요.");
for(int i = 0; i < 5; i++) {
intArray[i] = scanner.nextInt(); // 입력 받은 정수를 배열에 저장
if(intArray[i] > max)
max = intArray[i]; // max 변경
}
System.out.print("가장 큰 수는 " + max + "입니다.");
scanner.close();
}
}
8) 배열의 크기, length 필드
자바의 배열은 객체로 처리
배열 객체의 length 필드 : 배열의 크기는 배열 객체의 length 필드에 저장
size는 5
length 필드를 이용하여 배열의 모든 값을 출력하는 사례
for(int i = 0; i < intArray.length; i++) // intArray 배열 크기만큼 루프를 돈다.
System.out.println(intArray[i]);
import java.util.Scanner;
public class ArrayLength {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("5개의 정수를 입력하세요.");
int intArray[] = new int[5];
double sum = 0.0;
for(int i = 0; i < intArray.length; i++)
intArray[i] = scanner.nextInt(); // 키보드에서 입력받은 정수 저장
for(int i = 0; i < intArray.length; i++)
sum += intArray[i]; // 배열에 저장된 정수 값을 더하기
System.out.print("평균은 " + sum/intArray.length);
scanner.close();
}
}
5개의 정수를 입력하세요.
23459
평균은 4.6.
9) 배열과 for-each 문
배열이나 나열(enumeration)의 원소를 순차 접근하는데 유용한 for 문
for(int i = 0; i < n.length; i++) {
int k = n[i];
sum += k;
}
// for-each문으로 정수 배열의 합을 구함
int [] n = { 1, 2, 3, 4, 5};
int sum = 0;
for (int k : n) {
sum += k; // 반복될 때마다 k는 n[0], n[1], ..., n[4]로 번갈아 설정됨
}
public class foreachEx {
public static void main(String[] args) {
int [] n = { 1,2,3,4,5 };
int sum = 0;
for(int k : n) { // k는 n[0], n[1], ..., n[4]로 반복
System.out.print(k + " "); // 반복되는 k 값 출력
sum += k;
}
System.out.println("합은 " + sum);
String f[] = { "사과", "배", "바나나", "체리", "딸기", "포도" };
for(String s : f) // s는 f[0], f[1], ..., f[5]로 반복
System.out.print(s + " ");
}
}
1 2 3 4 5 합은 15
사과 배 바나나 체리 딸기 포도
10) 2차원 배열
2차원 배열 선언
2차원 배열 생성
2차원 배열의 구조
int i[][] = new int[2][5];
int size1 = i.length; // 2 : 2차원 배열의 행의 개수
int size2 = i[0].length; // 5 : 0번째 행의 열의 개수
int size3 = i[1].length; // 5 : 1번째 행의 열의 개수
11) 2차원 배열의 초기화
배열 선언과 동시에 초기화
int intArray[][] = {{ 0, 1, 2}, { 3, 4, 5}, {6, 7, 8}}; // 3x3 배열 생성
char charArray[][] = {{'a', 'b', 'c'}, {'d', 'e', 'f'}}; // 2x3 배열 생성
double doubleArray[][] = {{0.01, 0.02}, {0.03, 0.04}}; // 2x2 배열 생성
public class ScoreAverage {
public static void main(String[] args) {
double score[][] = {
{3.3, 3.4}, // 1학년 1, 2학기 평점
{3.5, 3.6}, // 2학년 1, 2학기 평점
{3.7, 4.0}, // 3학년 1, 2학기 평점
{4.1, 4.2} }; // 4학년 1, 2학기 평점
double sum = 0;
for(int year = 0; year < score.length; year++) // 각 학년별로 반복, 4
for(int term = 0; term < score[year].length; term++) // 각 학년의 학기별로 반복,2
sum += score[year][term]; // 전체 평점 합
int n = score.length; // 배열의 행 개수, 4
int m = score[0].length; // 배열의 열 개수, 2
System.out.println("4년 전체 평점 평균은 " + sum/(n*m));
} }
4년 전체 평점 평균은 3.725
12) 메소드의 배열 리턴
배열 리턴 : 배열의 레퍼런스만 리턴(배열 전체가 리턴되는 것이 아님)
메소드의 리턴 타입
- 리턴하는 배열타입과 리턴받는 배열타입 일치
- 리턴 타입에 배열의 크기를 지정하지 않음
메소드의 배열 리턴
public class ReturnArray {
static int[] makeArray() {
int temp[] = new int[4]; //makeArray()가 종료해도 생성된 배열은 소멸되지 않음.
for(int i = 0; i < temp.length; i++)
temp[i] = i; // 배열 초기화, 0, 1, 2, 3
return temp; // 배열 리턴
}
public static void main(String[] args) {
int intArray[];
intArray = makeArray(); // 메소드가 리턴한 배열 참조
for(int i = 0; i < intArray.length; i++)
System.out.print(intArray[i] + " ");
}
}
0123
3. 자바의 예외처리
1) 자바의 예외처리
예외(Exception)
- 실행 중 오동작이나 결과에 악영향을 미치는 예상치 못한 상황발생
- 자바에서는 실행 중 발생하는 에러를 예외로 처리
실행 중 예외가 발생하면
- 자바 플랫폼은 응용프로그램이 예외를 처리하도록 호출
- 응용프로그램이 예외를 처리하지 않으면 프로그램 강제 종료 시킴
예외 발생 경우
- 정수를 0으로 나누는 경우
- 배열의 크기보다 큰 인덱스로 배열의 원소를 접근하는 경우
- 정수를 읽는코드가 실행되고 있을때 사용자가 문자를 입력한 경우
2) 0으로 나누기 시 예외 발생 [예제 3-12]
import java.util.Scanner;
public class DivideByZero {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int dividend; // 나뉨수
int divisor; // 나눗수
System.out.print("나뉨수를 입력하시오:");
dividend = scanner.nextInt(); // 나뉨수 입력
System.out.print("나눗수를 입력하시오:");
divisor = scanner.nextInt(); // 나눗수 입력
System.out.println(dividend + "를 " + divisor + "로 나누면 몫은 " + dividend/divisor + "입니다."); //divisor가 0이므로 ArithmeticException예외 발생
}
}
나뉨수를 입력하시오:100
나눗수를 입력하시오:0
Exception in thread "main" java.lang.ArithmeticException: / by zero at DivideByZero.main(DivideByZero.java:13)
3) 자바의 예외처리, try-catch-finally 문
발생한 예외에 대해 개발자가 작성한 프로그램 코드에서 대응하는 것
- try-catch-finally 문 사용
- finally 블록은 생략 가능
try {
// 예외가 발생할 가능성이 있는 실행문(try 블록)
} catch (처리할 예외 타입 선언) {
// 예외 처리문(catch 블록)
} finally { // 생략가능
// 예외발생 여부와 상관없이 무조건 실행되는 문장 (finally 블록)
}
4) 예외가 발생/발생하지 않는 경우 제어의 흐름
생략
5) 자바의 예외 클래스
자바 플랫폼은 응용프로그램이 실행 중 오류를 탐지할 수 있도록 많은 예외를 클래스 형태로 제공
예외 타입(예외 클래스) | 예외 발생 경우 | 패키지 |
---|---|---|
ArithmeticException | 정수를 0으로 나눌 때 발생 | java.lang |
NullPointerException | null 레퍼런스를 참조할 때 발생 | java.lang |
ClasCastException | 변환할 수 없는 타입으로 객체를 변환할 때 발생 | java.lang |
OutOfMemoryError | 메모리가 부족한 경우 발생 | java.lang |
ArrayIndexOutOfBoundsException | 배열의 범위를 벗어난 접근 시 발생 | java.lang |
IllegalArgumentException | 잘못된 인자 전달 시 발생 | java.lang |
IOException | 입출력 동작 실패 또는 인터럽트 시 발생 | java.io |
NumberFormatException | 문자열이 나타나는 숫자와 일치하지 않는 타입의 숫자로 변환 시 발생 | java.lang |
InputMismatchException | Scanner 클래스의 nextInt()를 호출하고 정수로 입력받고자 하였지만, 사용자가 'a' 등과 같이 문자를 입력한 경우 | java.util |
배열의 범위를 벗어나 원소를 접근하는 예외 처리 ArrayIndexOutOfBoundsException 예외
int intArray [] = new int[5];
try {
intArray[3] = 10; // 예외 발생하지 않음
intArray[6] = 5; // 문장 실행 시 ArrayIndexOutOfBoundsException 예외 발생
} catch(ArrayIndexOutOfBoundsException e) { // 객체 e에 예외 정보가 넘어옴
System.out.println("배열의 범위를 초과하여 원소를 접근하였습니다.");
}
6) 0으로 나누는 예외에 대처하는 try-catch 블록
import java.util.Scanner;
public class DevideByZeroHandling {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int dividend; // 나뉨수
int divisor; // 나눗수
System.out.print("나뉨수를 입력하시오:");
dividend = scanner.nextInt(); // 나뉨수 입력
System.out.print("나눗수를 입력하시오:");
divisor = scanner.nextInt(); // 나눗수 입력
try {
System.out.println(dividend+"를 " + divisor + "로 나누면 몫은 " + dividend/divisor + "입니다.");
} catch(ArithmeticException e) { // ArithmeticException 예외 처리 코드
System.out.println("0으로 나눌 수 없습니다!");
} finally {
scanner.close(); // 정상적이든 예외가 발생하든 최종적으로 scanner를 닫는다.
}
}
}
나뉨수를 입력하시오:100
나눗수를 입력하시오:0
0으로 나눌 수 없습니다.
7) 입력 오류 시 발생하는 예외(InputMismatchException)
import java.util.Scanner;
import java.util.InputMismatchException;
public class InputException {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("정수 3개를 입력하세요");
int sum = 0, n = 0;
for(int i = 0; i < 3; i++) {
System.out.print(i+">>");
try {
n = scanner.nextInt(); // 정수 입력
} catch(InputMismatchException e) {
System.out.println("정수가 아닙니다. 다시 입력하세요!");
scanner.next(); // 입력 스트림에 있는 정수가 아닌 토큰을 버린다.
i--; // 인덱스가 증가하지 않도록 미리 감소
continue; // 다음 루프
}
sum += n; // 합하기
}
System.out.println("합은 " + sum);
scanner.close();
}
}
정수 3개를 입력하세요
0>>5
1>>R
정수가 아닙니다. 다시 입력하세 요!
1>>4 2>>6 합은 15