JAVA
[에센셜] CHP 3_2. 배열, 예외처리
제이지연
2022. 10. 9. 20:46
배열
배열 : 인덱스와 인덱스에 대응하는 일련의 데이터들로 이루어진 연속적인 자료구조
- 배열에는 같은 종류의 데이터들이 순차적으로 저장된다.
- 인덱스를 이용하여 원소 데이터 접근
- 반복문을 이용하여 처리하기에 적합한 자료구조
배열 선언 및 생성
- 배열에 대한 레퍼런스 변수 intArray 선언
intArray 변수는 레퍼런스(혹은 참조)라고 불리는 배열의 주소값을 가지며 그 자체가 배열은 아니다. 아직 배열이 생성되지 않았으므로 intArray 변수 값은 null.
int intArray[]; 또는 int [] intArray;
//배열타입
//배열에 대한 레퍼런스 변수
//배열 선언
int intArray[5]; //컴파일 오류. 선언시 배열의 크기를 지정하면 안된다
- 배열 생성
배열생성은 배열공간을 할당받는 과정. new 연산자를 이용하여 배열을 생성한다. 생성된 배열에 대한 레퍼런스를 intArray에 대입.
intArray=new int [5];
//배열에 대한 레퍼런스 변수
//배열 생성
//타입
//원소 개수
선언과 생성을 동시에
int intArray[]=new int [5];
- 배열 초기화
크기는 자동으로 정해진다.
int intArray[] = {1,2,3,4,5};
double doubleArray[] = {0.1, 1.2, 2.3};
배열 인덱스와 배열 원소 접근
- 배열의 인덱스는 정수만 가능
- 인덱스는 0부터 시작
- 음수인덱스나 범위를 넘어선 인덱스는 실행 오류가 난다.
- 배열이 생성되어 있지 않은 상태에서 배열을 사용하면 오류발생
레퍼런스 치환과 배열 공유
배열공간과 레퍼런스 변수가 분리되어 있기 때문에 생성된 배열에 대한 공유가 쉽게 이루어진다. 생성된 배열을 다수의 레퍼런스가 참조할 수 있다.
int intArray[] = new int[5];
int newArray[] = intArray; //레퍼런스 치환. 동일한 배열을 참조
예제3-7. 배열 선언 및 생성
import java.util.Scanner;
public class ArrayAccess {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner scanner = new Scanner(System.in);
int intArray[];
intArray=new int[5];
//int 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();
}
}
배열의 크기, length 필드
- 자바는 배열을 객체로 다룬다.
- 배열이 생성되면 배열공간과 같이 배열의 크기 값을 가진 length 필드가 배열 객체 내에 생성된다.
int intArray[]=new int [5];
int size = intArray.length;
for문에서의 사용
for(int i=0;i<intArray.length;i++)
System.out.println(intArray[i]);
메소드에 배열을 전달할 경우 c와 달리 배열의 크기를 전달할 필요가 없다.
예제3-8. 배열의 length 필드 활용
public class ArrayAccess2 {
static int sum(int x[]) {
int n, s=0;
System.out.println(x);
for(n=0;n<x.length;n++)
s+=x[n];
//x[2]=100;
return s;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
int a[]= {1,2,3,4,5};
int b[]=a;
int c[]= {10,20,30,40,50,60,70,80};
int n=sum(a); //n=15;
System.out.println(n);
System.out.println(a);
System.out.println(b);
System.out.println("a[1], b[1] ==================");
a[1]=10;
System.out.println(a[1]);
System.out.println(b[1]);
System.out.println("a[2], b[2], c[2] ==================");
System.out.println(a[2]);
System.out.println(b[2]);
System.out.println(c[2]);
System.out.println("length ==================");
System.out.printf("length of a = %d\n", a.length);
System.out.printf("length of b = %d\n", b.length);
System.out.printf("length of c = %d\n", c.length);
c=a;
System.out.println(c[2]);
System.out.printf("length of a = %d\n", a.length);
System.out.printf("length of b = %d\n", b.length);
System.out.printf("length of c = %d\n", c.length);
}
}
배열과 for-each 문
for-each문은 배열이나 나열(enumeration)의 크기만큼 루프를 돌면서, 각 원소를 순차적으로 접근하는데 매우 유용.
for(변수 : 배열레퍼런스) {
...반복작업문...
}
int []n={1,2,3,4,5};
int sum=0;
for(int k:n) //n.length만큼 반복
sum+=k;
예제3-9. for-each문 활용
public class ForEachEx {
public static void main(String[] args) {
// TODO Auto-generated method stub
int []n = {1,2,3,4,5};
int sum=0;
for(int k:n) {
System.out.print(k+" ");
sum+=k;
}
System.out.println("합은 "+sum);
String f[]= {"사과","배","바나나","체리","딸기","포도"};
for(String s : f) {
System.out.print(s+" ");
}
}
}
2차원 배열의 선언과 생성
- 2차원 배열의 레퍼런스 변수 선언
int intArray[][]; 또는 int [][] intArray;
- 2차원 배열의 생성
intArray = new int[2][5];
동시에
int intArray[][] = new int [2][5];
2차원 배열의 초기화
int intArray[][]={{1,2,3},{4,5,6}} //2x3배열 생성
char charArray[][]={{'a','b'},{'c','d'}}//2x2배열 생성
예제3-10. 2차원 배열 생성 및 활용하기
import java.util.Random;
import java.util.Scanner;
public class Matrix_0 {
public static void main(String[] args) {
// TODO Auto-generated method stub
int mat[][] = new int [9][9];
int row=9, col=9, r, c;
for(r=0;r<row;r++)
for(c=0;c<col;c++)
mat[r][c] = (int)(Math.random()*10 +1);
System.out.println();
System.out.println("생성한 9x9 Matrix");
for(r=0;r<row;r++) {
for(c=0;c<col;c++)
System.out.printf("%3d", mat[r][c]);
System.out.println();
}
}
}
메소드
메소드가 배열을 리턴하는 경우, 배열 메모리 전체가 아니라 배열에 대한 레퍼런스만 리턴된다.
int[] makeArray(){ //리턴타입 메소드이름
int temp[] = new int[4];
return temp; //배열 리턴
}
예제3-11. 배열 리턴
public class MakeArray {
static int[] makeArray(int N) { //일차원 정수 배열 리턴
int temp[] = new int[N]; //배열생성
for(int i=0;i<N;i++)
temp[i]=i;
return temp; //배열 리턴
}
public static void main(String[] args) {
// TODO Auto-generated method stub
int intArray[]; //배열 레퍼런스 변수 선언
intArray=makeArray(5); //메소드가 리턴한 배열 참조
System.out.print(intArray+ " --> ");
for(int i=0;i<intArray.length;i++) {
System.out.print(intArray[i]+" ");
}
System.out.println();
intArray=makeArray(10); //메소드가 리턴한 배열 참조
System.out.print(intArray+ " --> ");
for(int i=0;i<intArray.length;i++) {
System.out.print(intArray[i]+" ");
}
System.out.println();
intArray=makeArray(7); //메소드가 리턴한 배열 참조
System.out.print(intArray+ " --> ");
for(int i=0;i<intArray.length;i++) {
System.out.print(intArray[i]+" ");
}
System.out.println();
}
}
예외 처리
예외 : 실행 중 오동작이나 결과에 악영향을 미치는 예상치 못한 상황 발생을 말한다. 실행중에 예외가 발생하면 자바 플랫폼이 가장 먼저 알게되어, 현재 실행중인 자바 응용프로그램에게 예외를 전달하여 응용프로그램이 예외에 대응.
- 정수를 0으로 나누는 경우
- 배열의 크기보다 큰 인덱스로 배열의 원소를 접근하는 경우
- 정수를 읽는 코드가 실행되고 있을 때 사용자가 문자를 입력한 경우
자바의 예외처리, try-catch-finally문
catch블록은 예외마다 하나씩 작성되어야 한다. 만일 발생한 예외 타입과 일치하는 catch블록이 없으면 프로그램은 강제 종료된다. ㅡ
try{
예외가 발생할 가능성이 있는 실행문(try block)
}
catch(처리할 예외 타입 선언){
예외 처리문(catch block)
}
finally{
생략가능, 예외발생여부와 상관없이 무조건 실행되는 문장
}
자바의 예외 클래스
예외타입
|
예외발생경우
|
ArithmeticException
|
정수를 0으로 나눌 때 발생
|
OutOfMemoryError
|
메모리가 부족한 경우 발생
|
ArrayIndexOutOfBoundsException
|
배열의 범위를 벗어난 접근 시 발생
|
int intArray[] = new int [5];
try{
intArray[3] = 10;
intArray[6] = 5; //예외 발생
}
catch (ArrayIndexOutOfBoundsException e){ //객체 e에 예외 정보가 넘어옴
System.out.println("배열의 범위 초과");
}
예제3-12. 0으로 나누기 시 예외 발생으로 응용프로그램이 강제 종료되는 경우
import java.util.Scanner;
public class DivideByZero{
public static void main(String[] args){
Scanner scanner = new Scanner(System.in);
int divided; //나뉨수
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){
System.out.println("0으로 나눌수 없습니다.!");
}
finally{
scanner.close();
}
}}