[6주차] 자바 프로그래밍

Useful·2023년 4월 11일
0

Java

목록 보기
2/10
post-thumbnail

[지난 5주차에 이어서 계속..]

2차원 배열

2차원 배열은 하나의 테이블이라고 생각하면 된다

  • Java의 2차원 배열은 행우선 기법을 사용한다. 라고 알아놓자

2차원 배열의 구성

// 2차원 배열 선언
int intArray[][];		또는		int[][] intArray;
char charArray[][];     또는  	char[][] charArray;

// 2차원 배열 생성
intArray = new int[2][5];		또는		int intArray[][] = new int[2][5];
charArray = new int[5][5];	    또는		char charArray[][] = new char[5][5];

// 2차원 배열 선언, 생성, 초기화
int intArray[][] = {{0,1,2},{3,4,5},{6,7,8}};

2차원 배열의 모양과 length 필드

int i[][] = new int[2][5];
int size1 = i.length;		// 2
int size2 = i[0].length;	// 5
int size3 = i[1].length;	// 5

// i 는 전체 반장 느낌이고
// i[0]과 i[1]은 줄반장이다
// i.length    -->  2차원 배열의 행의 개수
// i[n].length -->  n번째 행이 가지고 있는 열의 개수



예제 : 2차원 배열 사용

2차원 배열을 사용하여 3년 동안의 평균 학점을 내는 프로그램을 작성

package test;

public class ScoreAverage {

	public static void main(String[] args) {
    	// 학점 초기값 {1학기, 계절학기, 2학기, 계절학기} ..
		double[][] score = 
			{
				{4.2, 4.1, 3.8, 4.3},	// 1학년
				{3.9, 3.5, 4.4, 4.1},	// 2학년
				{4.5, 4.4, 4.3, 4.5},	// 3학년
			};
		
		double sum = 0.0;
		
		for(int year=0; year<score.length; year++) {
			for(int yScore=0; yScore<score[year].length; yScore++) {
				sum += score[year][yScore];
			}
		}
        
        int n = score.length;		//배열의 행 개수, 3
        int m = score[0].length;	//배열의 열 개수, 4
		
		System.out.println("평균: " + sum/(n*m));
		// 결과 : 평균: 4.166666666666667
	}
}

비정방형 배열

정방형 배열이란?

  • 각 행의 열의 개수가 같은 배열
int i[][];
i = new int[4][4];

/* [위에 선언한 정방형 배열(기본)의 구조]

  i[0][0] i[0][1] i[0][2] i[0][3]
  i[1][0] i[1][1] i[1][2] i[1][3]
  i[2][0] i[2][1] i[2][2] i[2][3]
  i[3][0] i[3][1] i[3][2] i[3][3]

*/

비정방형 배열이란?

  • 각 행의 열의 개수가 다른 배열
  • 비정방형 배열의 생성
int i[][];
i = new int[4][];

i[0] = new int [1];
i[1] = new int [2];
i[2] = new int [3];
i[3] = new int [4];

/* [위에 선언한 비정방형 배열의 구조]
i[0] = new int [1]; == i[0][0]
i[1] = new int [2]; == i[1][0] i[1][1]
i[2] = new int [3]; == i[2][0] i[2][1] i[2][2]
i[3] = new int [4]; == i[3][0] i[3][1] i[3][2] i[3][3]
*/

비정방향 배열의 length

int i[][];
i = new int[4][];

i[0] = new int [1];
i[1] = new int [2];
i[2] = new int [3];
i[3] = new int [4];


/* 각 배열의 길이는 다음과 같다..
	i[0].length = 1
    i[1].length = 2
    i[2].length = 3
    i[3].length = 4
*/

예제 : 비정방형 배열의 생성과 접근

package test;

public class lrregularArray {

	public static void main(String[] args) {
		int intArray[][] = new int[4][];
		intArray[0] = new int[3];
		intArray[1] = new int[2];
		intArray[2] = new int[3];
		intArray[3] = new int[2];
		
		for(int i=0; i<intArray.length; i++) {
			for(int j=0; j<intArray[i].length; j++) {
				intArray[i][j] = (i+1)*10 + j;
			}
		}
		
		for(int i=0; i<intArray.length; i++) {
			for(int j=0; j<intArray[i].length; j++) {
				System.out.print(intArray[i][j] + " ");
			}
			System.out.println();
		}
	}

}
/* 결과 : 
  10 11 12 
  20 21 
  30 31 32 
  40 41 
*/

예제 2 : 비정방형 배열의 구조를 *로 찍어보기

package test;

public class lrregularArray {

	public static void main(String[] args) {
		int intArray[][] = new int[4][];
		intArray[0] = new int[3];
		intArray[1] = new int[2];
		intArray[2] = new int[3];
		intArray[3] = new int[2];
		
		for(int i=0; i<intArray.length; i++) {
			for(int j=0; j<intArray[i].length; j++) {
				intArray[i][j] = (i+1)*10 + j;
				System.out.print(intArray[i][j] + " ");
			}
			System.out.println();
		}
	}
}
// 결과 : 
/*
******
**
*****
****
*/

다음으로 넘어가기 전,

인자(Argument), 매개변수(Parameter)의 차이

매개변수(parameter)는 함수를 정의할 때 사용되는 변수 이고,

인자(Argument)는 실제로 함수가 호출될 때 넘기는 변수값이다.

// 나이(year)를 받아 연금값을 return하는 함수 calcNum

// 'int year'는 파라미터이다.
int calcNum(int year) {
	int res = year * 천만원(대충 정수);
    return res;
}

calcNum(50); // 50은 argument가 된다.

// 결과 : 5억

메소드(method)에서 배열 리턴

  • 메소드의 배열 리턴
    • 배열의 레퍼런스 리턴
    • 메소드의 리턴 타입
      • 메소드의 리턴 타입과 리턴 받는 배열 타입과 일치
      • 리턴 타입에 배열의 크기를 지정하지 않음
// int[] 즉, 리턴 타입에 배열 크기를 지정하지 않음.
int[] makeArray() {
	int temp[] = new int[4];
    return temp;  // 배열의 레퍼런스(int temp[]) 리턴
}

// 메소드의 리턴 타입(int)와 리턴 받는 배열 타입(int)과 일치
int[] intArray;
intArray = makeArray();

예제 : 배열 리턴

배열을 리턴하는 makeArray()를 작성하고, 이 메소드에게 파라미터로 배열의 크기(size)를 전달, 그리고 이 메소드로부터 배열을 전달받아 값을 출력하는 프로그램을 작성하라

package test;

public class ReturnArray {

	// main 함수가 static이기 때문에, makeArray도 static으로 선언
	static int[] makeArray(int size) {
		int temp[] = new int[size];		// 파라미터로 받은 size 크기만큼 배열 생성
		
		for(int i=0; i<temp.length; i++) {
			temp[i] = i+1;	// 배열의 원소를 i+1 ~ size + 1로 초기화
		}
		
		return temp;	// 배열 리턴
		
	}
    
    // main method
	public static void main(String[] args) {
		int arp[] = makeArray(10);	// 배열 레퍼런스 변수를 선언 하고, 메소드로부터 배열 전달받음
		
		for(int i=0; i<arp.length; i++) {
			System.out.print(arp[i] + " ");		// 배열의 원소 출력
		}
	}

}
/* 결과 : 
	1 2 3 4 5 6 7 8 9 10 
*/

main() 메소드

main()은 자바 응용프로그램의 실행 시작 메소드 (중요!)

  • main()의 원형
    • 반드시 static
    • 반드시 public
    • 반드시 void
    • 반드시 매개 변수 타입은 문자열 배열 (string[] args)
// 자바의 시작점인 main method
public static void main(string[] args) {
	...대충 내용이라는 뜻...
}

main(string [] args) 메소드의 인자 전달

  1. 이클립스 상단 [run]
  2. [Run Configurations] 클릭
  3. [Java Application] > [설정할 class] 클릭
  4. [Argument] 탭에 Program arguments: 안에 데이터 입력
  5. 위의 방식으로 main method의 파라미터인 string[] args에 인자값(arguments)을 전달 할 수 있음.

자바의 예외 처리

  • 컴파일 오류 ?

    • 문법에 맞지 않게 작성된 코드
    • 컴파일할 때 발견
  • 예외(Exception) ?

    오동작이나 결과에 악영향을 미칠 수 있는 실행 중 발생한 오류
    • 정수를 0으로 나누는 경우
    • 배열보다 큰 인덱스로 배열의 원소를 접근하는 경우
    • 존재하지 않는 파일을 읽으려고 하는 경우
    • 정수 입력을 기다리는 코드가 실행되고 있을 때, 문자가 입력된 경우
    • 자바에서 예외 처리 가능
      • 예외 발생 -> 자바 플랫폼 인지 -> 응용프로그램에서 전달
        • 응용프로그램이 예외를 처리하지 않으면, 응용프로그램 강제 종료
	double func1 (int x) {
    	if(x의 처리결과 == 위험) {
        	throw(Exception 객체);
        } // 오잉 throw가 있네?
    }

throw와 throws, 그리고 그 차이점

throw..? 뭘 던진다는 것인가요

던지긴 한다... 예외(Exception)를 야구공이라 생각하고 던지는(throw) 개념이다.

일단! 예외(Exception)는 프로그래머가 짠 로직에 의해 생긴다.
     → 오류 생기면 우리 잘못이라는 의미


그러면 우리가 예외(Exception)을 강제로 발생시킬 수 있나요?

고렇다. 강제로 프로그램에게 예외를 발생시키는 명령어가 존재한다.
그것이 바로 .. throwthrows 이다.


throw

강제로 예외를 발생시킨 후 상위블럭이나 catch문으로 예외를 던진다.

public class ThrowExceptionTest {

	public static void main(String[] args) {
		try {
			myException();	// (1) main 메소드에서 myException() 함수를 호출했다. 
		} catch(Exception e) {
			System.out.println("main method 에서 예외가 발생!");
		}
	}
	static void myException() {
		try {
			throw new Exception(); // (2) throw문을 통해서 예외(Exception)를 강제로 발생
		} catch(Exception e) {
       	 	// (3) 그래서 catch 블럭으로 넘어오게 되었음.
			System.out.println("myException에서 예외 발생!");
		}
	}
    // 결과 : myException에서 예외 발생!
}

위 코드로 알 수 있는 것은..
1. throw 를 통해 강제로 예외를 발생 시킬 수 있구나..!
2. 때문에 발생된 예외를 통해 catch 블럭으로 넘어가게 되는구나..!


throws

throws는 예외가 발생하면 상위메서드로 예외를 던진다.

public class ThrowExceptionTest {

	public static void main(String[] args) {
		try {
			myException();
		} catch(Exception e) {
			System.out.println("main method 에서 예외가 발생!");
		}
	}
    
	static void myException() throws Exception {
    	throw new Exception();
    }
}
// 결과 : main method 에서 예외가 발생!

아니 왜 myException 메서드 안에는 왜 try-catch문 안씀?

위에서 서술한 것과 같이, throws는 예외가 발생하면 예외를 상위메서드로 던진다.
예외에 대한 처리를 호출부로 위임하기 때문이다.

그냥 쉽게 말하면

myException : 너가 나 불렀지 main 메소드야? 근데 나 에러났음. 니가 내 에러난거 책임져
main : ㅠㅠ

와 같다.....

예제 : 0으로 나누기 예외 발생으로 프로그램이 강제 종료되는 경우

두 정수를 입력받아 나눗셈을 하고 몫을 구하는 프로그램

package test;

import java.util.Scanner;

public class DiviedByZero {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int dividend;
		int divisor;
		
		System.out.print("나뉨수를 입력하시오:");
		dividend = sc.nextInt();
		
		System.out.print("나눗수를 입력하시오:");
		divisor = sc.nextInt();
		
		System.out.println(dividend + "를" + divisor + "로 나누면 몫은" + dividend/divisor + "입니다.");	//divisor가 0이므로 예외 발생
		sc.close();
	}
}
/* 결과 : 
  나뉨수를 입력하시오: 100
  나눗수를 입력하시오: 0
  Exception in thread "main" java.lang.ArithmeticException: / by zero
      at test.DiviedByZero.main(DiviedByZero.java:18)
*/

예외처리, try-catch-finally 문

  • 예외처리
    • 예외가 발생할 때 대응하는 응용프로그램 코드
    • try-catch-finally 문 사용
      • finally 블록은 생략 가능
	try {
    	예외가 발생할 가능성이 있는 실행문 (try 블록)
    }
    catch (처리할 예외 타입 선언) {
    	예외 처리문 (catch 블록)
    }
    finally {
    	예외 발생 여부와 상관없이 무조건 실행되는 문장 (finally 블록)
    }

예제 : 0으로 나눌 때 발생하는 AirthmeticException 예외 처리

package test;

import java.util.Scanner;

public class DiviedByZero {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		
		while(true) {
			int dividend;
			int divisor;
			
			System.out.print("나뉨수를 입력하시오:");
			dividend = sc.nextInt();
			
			System.out.print("나눗수를 입력하시오:");
			divisor = sc.nextInt();
			
			try {
				System.out.println(dividend + "를" + divisor + "로 나누면 몫은" + dividend/divisor + "입니다.");	//divisor가 0이므로 예외 발생	
			} 
			catch(ArithmeticException e) {	//ArithmeicException 예외 처리 코드
				System.out.println("0으로 나눌 수 없습니다! 다시 입력하세요.");
			}
			
		}
	}
}
/*
결과 : 
  나뉨수를 입력하시오:100
  나눗수를 입력하시오:0
  0으로 나눌 수 없습니다! 다시 입력하세요.
  나뉨수를 입력하시오:100
  나눗수를 입력하시오:5
  100를5로 나누면 몫은20입니다.
*/




예제 : 범위를 벗어난 배열의 접근

배열의 인덱스가 범위를 벗어날 때 발생하는 ArrayOutOfBoundsException을 처리하는 프로그램을 작성하시오.

package test;

public class ArrayException {

	public static void main(String[] args) {
		int [] intArray = new int[5];
		intArray[0] = 0;
		try {
			for(int i=0; i<5; i++) {
				// i가 4일 때 ArrayIndexOutOfBoundsException 예외 발생
				intArray[i+1] = i+1 +intArray[i];
				System.out.println("intArray["+i+"]"+"="+intArray[i]);
			}
		}catch(ArrayIndexOutOfBoundsException e) {
			System.out.println("배열의 인덱스가 범위를 벗어났습니다.");
		}

	}

}
/*
결과 : 
  intArray[0]=0
  intArray[1]=1
  intArray[2]=3
  intArray[3]=6
  배열의 인덱스가 범위를 벗어났습니다.

*/

예제 : 입력오류시발생하는 예외(InputMismatchException)

package test;

import java.util.*;
import java.util.InputMismatchException;

public class InputException {

	public static void main(String[] args) {
		Scanner sc = 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 {	// 사용자가 문자를 입력하면 InputMismatchException 예외 발생
				n = sc.nextInt(); //정수 입력
			} 
			catch(InputMismatchException e) {
				System.out.println("정수가 아닙니다. 다시 입력하세요!");
				sc.next();	// 입력 스트림에 있는 정수가 아닌 토큰을 버린다.
				i--;		// 인덱스의 증가를 방지
				continue;	// 다음 루트
			}
			sum += n;	// 합하기
		}
		System.out.println("합은 " + sum);
		sc.close();
	}

}
/* 결과 : 
정수 3개를 입력하세요
  0>>5
  1>>R
  정수가 아닙니다. 다시 입력하세요!
  1>>5
  2>>10
  합은 20
*/
profile
1 commit = 1 life

0개의 댓글