Difference between revisions of "컴퓨터프로그래밍및실습 (2022년)/0919"

From DISLab
Jump to navigation Jump to search
 
(8 intermediate revisions by the same user not shown)
Line 356: Line 356:
         String[] newStrArray = new String[5];
         String[] newStrArray = new String[5];


         System.arraycopy(oldStrArray, 0, newStrArray, 0, oldIntArray.length);
         System.arraycopy(oldStrArray, 0, newStrArray, 0, oldIntArray.length); // p.169 그림 참조


         for(int i = 0; i < newStrArray.length; i++)
         for(int i = 0; i < newStrArray.length; i++)
Line 374: Line 374:
=== 향상된 for 문 ===
=== 향상된 for 문 ===
<syntaxhighlight lang="java">
<syntaxhighlight lang="java">
public class ArrayCopyExample {
    public static void main(String[] args) {
        // for 문 이용
        int[] oldIntArray = { 1, 2, 3 };
        int[] newIntArray = new int[5];
        for(int i = 0; i < oldIntArray.length; i++)
            newIntArray[i] = oldIntArray[i];
        for(int value : newIntArray) // ← 배열 전체를 스캔하는데 인덱스가 필요없음
            System.out.print(value + "," );
        System.out.println();
        // arraycopy 이용
        String[] oldStrArray = { "java", "array", "copy" };
        String[] newStrArray = new String[5];
        System.arraycopy(oldStrArray, 0, newStrArray, 0, oldIntArray.length);


        for(String str : newStrArray) // ← 배열 전체를 스캔하는데 인덱스가 필요없음
            System.out.print(str + ", ");
        System.out.println();
    }
}
</syntaxhighlight>
</syntaxhighlight>


== 열거 타입 ==
== 열거 타입(Enumeration Type) ==
* Java에서 이름 짓는 법
<table2 class=wikitable head=top sep=bar align=lll>
종류                      | 예                  | 설명
변수                      | name                | 소문자를 이용하여 짓는다. 영어가 아닌 한국어로 변수 이름을 지어도 되지만 관례적으로 로마자를 사용한다.
                          | myName, myFirstName | 두 개의 단어가 연이어 나오면 새로운 단어의 시작은 대문자로 한다.
메소드                    | move()              | 소문자로 짓는다. 이름 뒤에 연이어 괄호가 나오기 때문에 이름으로 변수와 메소드를 구분할 수 있다.
                          | moveLeft()          | 두 개의 단어가 연이어 나오면 새로운 단어의 시작은 대문자로 한다.
클래스, 인터페이스, 열거형 | Car                | 시작 문자를 대문자로 한다.
                          | BlueCar            | 두 개의 단어가 연이어 나오면 새로운 단어의 시작은 대문자로 한다.
상수(static final)        | COLOR              | 모든 문자를 대문자로 한다.
                          | BLUE_COLOR          | 두 개의 단어가 연이어 나오면 단어 사이에 _를 붙인다.
</table2>
 
=== 열거 타입 선언 ===
 
* 상수를 여러 개 만들고 싶을 때
<syntaxhighlight lang="java">
<syntaxhighlight lang="java">
public enum Week { MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY };
public enum LoginResult { LOGIN_SUCCESS, LOGIN_FAILED };
Week today;
Week reservationDay;
Week birthday = null;
today = Week.SUNDAY;
if (today == Week.SUNDAY) { // true
</syntaxhighlight>
* Calendar 객체를 이용한 열거형 연습
<syntaxhighlight lang="java">
Calendar now = Calendar.getInstance();
int year = now.get(Calendar.YEAR); // 년
int month = now.get(Calendar.MONTH) + 1; // 월
int day = now.get(Calendar.DAY_OF_MONTH); // 일
int week = now.get(Calendar.DAY_OF_WEEK); // 요일 (1~7)
int hour = now.get(Calendar.HOUR); // 시간
int minute = now.get(Calendar.MINUTE); // 분
int second = now.get(Calendar.SECOND); // 초
</syntaxhighlight>
=== 열거 객체의 메소드 ===
* 열거 객체는 java.lang.Enum 클래스로부터 상속받음.
<table2 class=wikitable head=top sep=bar align=lll>
리턴 타입 | 메소드(매개 변수)    | 설명
String    | name()              | 열거 객체의 문자열을 리턴
int      | ordinal()            | 열거 객체의 순번(0부터 시작)을 리턴
int      | compareTo()          | 열거 객체를 비교하여 순번 차이를 리턴
열거 타입 | valueOf(String name) | 주어진 문자열의 열거 객체를 리턴
열거 배열 | values()            | 모든 열거 객체들을 배열로 리턴
</table2>
<syntaxhighlight lang="java">
Week today = Week.SUNDAY;
String name = today.name(); // "SUNDAY"
int ordinal = today.ordinal(); // 6. 0부터 시작하여 6번째 데이터라는 뜻임
Week day1 = Week.MONDAY;
Week day2 = Week.WEDNESDAY;
int result1 = day1.compareTo(day2); // -2 (0 - 2)
int result2 = day2.compareTo(day1); // 2 (2 - 0)
Week weekDay = Week.valueOf("SATURDAY"); // Week.SATURDAY


Week[] days = Week.values();
for(Week day : days)
    System.out.println(day);
</syntaxhighlight>
</syntaxhighlight>




[[category:컴퓨터프로그래밍및실습]]
[[category:컴퓨터프로그래밍및실습]]

Latest revision as of 18:04, 26 September 2022

데이터 타입 분류

  1. 기본 타입(primitive type)
    • 정수 타입
      • byte
      • char
      • short
      • int
      • int
      • long
    • 실수 타입
      • float
      • double
    • 논리 타입
      • boolean
  2. 참조 타입(reference type)
    • 배열 타입(array type)
    • 열거 타입(enumeration type)
    • 클래스(class)
    • 인터페이스(interface)
// 기본 타입 변수
int age = 25;
double price = 100.5

// 참조 타입 변수(reference type variable)
String name = "신용권"; // 객체는 힙(heap) 영역에 존재한다.
String hobby = "독서";
  • 참조 변수인 name에는 "신용권" 객체가 저장되어 있는 메모리의 주소가 저장되어 있다.
  • 교재 p.139 그림 참조

메모리 사용 영역

  • 교재 p.140 그림 참조
  1. 메소드(method) 영역
    • Java 소스 코드(XXX.java)를 컴파일하여 만들어진 실행 코드(bytecode) (XXX.class)가 적재된 메모리 영역
    • 클래스 로더(class loader)가 class 파일을 읽어 메모리에 올림
    • 상수풀(runtime constant pool), 필대(field) 데이터, 메소드(method) 데이터, 메소드 코드, 생성자(construct) 코드 등 실행에 필요한 바이트코드 및 상수, 전역 변수(클래스 변수, class field)
  2. 힙(heap) 영역
    • 프로그래머가 생명 주기(life time)을 제어할 수 있는 메모리가 위치하는 영역임
    • new 연산자를 이용하여 생성하는 객체
    • 배열, String도 객체이므로 힙에 존재함
    • new 연사자를 호출하여 객체를 생성하면 만들어지고, garbage가 되면 사라짐
  3. 스택(stack) 영역
    • 스택 영역은 스레드 마다 독립적으로 존재함
    • 특별히 스레드를 만들지 않았다면 main 메소드가 실행되고 있는 main 스레드만 존재하므로 스택 영역도 하나임
    • 메소드의 인자, 지역 변수(local variable), 리턴 값, 리턴 주소가 저장됨. 이를 activation record라 부름.
    • p.142 그림 참조
  • 아래 코드에서 (1), (2), (3) 지점에서의 스택 영역의 형태는?
char v1 = 'A'; // (1)

if (v1 == 'A') { // (2)
    int v2 = 100;
    double v3 = 3.14;
}

boolean v4 = true; // (3)

참조 변수의 ==, != 연산

  • 교재 p.143 그림 참조
refVar1 = 객체_1;
refVar2 = 객체_2;
refVar3 = 객체_2;

refVar1 == refVar2  // 결과 : false
refVar1 != refVar2  // 결과 : true

refVar2 == refVar3  // 결과 : true
refVar2 != refVar3  // 결과 : false

null과 NullPointerException

refVar1 = 객체_1;
refVar2 = null;

refVar1 == null // 결과 : false
refVar1 != null // 결과 : true

refVar2 == null // 결과 : true
refVar2 != null // 결과 : false

int[] intArray = null;
intArray[0] = 10;  // NullPointerException 발생

String str = null;
System.out.println("총 문자수 : " + str.length()); // NullPointerException 발생

String 타입

  • String은 상수 객체이다. 왜냐하면 String에는 자신이 가진 값을 변경하는 메소드가 없기 때문이다.
String 변수 = "문자열";

String name;
name = "신용권";

String hobby = "자바";
hobby = null; // garbage가 된다.

String name1 = "신용권";
String name2 = "신용권"; // 리터럴이 동일하면 동일한 객체를 가리킴

name1 = "신민철";
name2 = "신민철";
String name3 = new String("신민철");

boolean result = name1 == name2; // true
result = name1 == name3; // false
result = name1.equals(name3); // true;

배열 타입

  • 동일한 타입을 여러 개 만들어야 할 때

배열이라?

  • 다음은 성가시다.
int score1 = 83;
int score2 = 90;
int score3 = 87;
int score4 = 99;
int score5 = 48;
int score6 = 21;
int score7 = 38;
int score8 = 83;
int score9 = 78;
int score10 = 92;
int score11 = 95;
int score12 = 29;
int score13 = 55;
int score14 = 66;
int score15 = 88;
int score16 = 77;
int score17 = 44;
int score18 = 34;
int score19 = 84;
int score20 = 81;
int score21 = 60;
int score22 = 85;
int score23 = 44;
int score24 = 23;
int score25 = 84;
int score26 = 48;
int score27 = 40;
int score28 = 58;
int score29 = 78;
int score30 = 75;
  • 평균을 구하고자 한다면 코드를 어떻게 작성해야 하나?
int sum = score1;
sum += score2;
sum += score3;
sum += score4;
sum += score5;
sum += score6;
sum += score7;
sum += score8;
sum += score9;
sum += score10;
sum += score11;
sum += score12;
sum += score13;
sum += score14;
sum += score15;
sum += score16;
sum += score17;
sum += score18;
sum += score19;
sum += score20;
sum += score21;
sum += score22;
sum += score23;
sum += score24;
sum += score25;
sum += score26;
sum += score27;
sum += score28;
sum += score29;
sum += score30;

int avg = sum / 30;
  • 얼마나 번거러운가? 아래와 같이 바꿔보자.
// score는 배열이다.
int[] score = {83, 90, 87, 99, 48, 21, 38, 83, 78, 92, 95, 29, 55, 66, 88, 77, 44, 34, 84, 81, 60, 85, 44, 23, 84, 48, 40, 58, 78, 75};

int sum = 0;
for(int i = 0; i < score.length; i++)  // 여기서 score.length는 30
    sum += score[i]; // score[0]는 83, score[1]은 90 ...
int avg = sum / score.length;
  • 왜 배열이 필요한지 이해가 되는가?

배열 선언

  • 두 표현은 동일하다.
int[] intArray; int intArray[];
double[] doubleArray; double doubleArray[];
String[] strArray; String strArray[]

  • 참고할 배열이 없다면 null로 지정한다.
int[] intArray = null;

값 목록으로 배열 선언

String[] names = { "신용권", "홍길동", "감자바" };

names[1] = "홍삼원";

//--------------------------------------

String[] names = null;
names = new String[] { "신용권", "홍길동", "감자바" };

//--------------------------------------

// 다음과 같은 add 메소드가 있다면
int add(int[] scores) {
    int sum = 0;
    for(int i = 0; i < scores.length; i++)
        sum += scores[i];
    return sum;
}

// 이를 호출하는 방법으로
int result = add( {95, 85, 90} ); // 컴파일 에러 발생

int result = add( new int[] {95, 85, 90} ); // OK

new 연산자로 배열 생성

int[] scores = new int[30]; // 앞의 예제에서 빈 배열을 만들고자 한다면. 모두 0으로 초기화된다.
scores[0] = 83; // 인덱스는 0부터 시작한다.
scores[1] = 90;
scores[2] = 75;

String[] names = new String[30]; // 모두 null로 초기화된다.
names[0] = "신용권";
names[1] = "홍길동";
names[2] = "감자바";

배열 길이

int[] intArray = { 10, 20, 30 };
System.out.println(intArray.length); // 3이 출력됨

intArray.length = 10; // 에러. length는 상수이다. 즉, 값을 변경할 수 없다.

커맨드 라인(command line) 입력

  • 명령창에서 다음과 같이 Java 프로그램 실행
C:> java MainStringArrayArgument 10 20
  • 코드
public class MainStringArrayArgument {
    public static void main(String[] args) {
        if (args.length != 2) { // 입력 데이터가 2개가 아닌 경우
            System.out.println("Usage: java MainStringArrayArgument num1 num2");
            System.exit(0); // 프로그램 강제 종료
        }

        String strNum1 = args[0];
        String strNum2 = args[1];

        int num1 = Integer.parseInt(strNum1); // Integer 클래스의 parseInt 메소드를 이용하여 문자열을 정수로 변환
        int num2 = Integer.parseInt(strNum2);

        int result = num1 + num2;
        System.out.println(num1 + "+" + num2 + "=" + result);
    }
}
  • 실행 결과
10+20=30

다차원 배열

int[][] scores = new int[2][3];

System.out.println(scores.length);  // 2
System.out.println(scores[0].length); // 3
System.out.println(scores[1].length); // 3

//--------------------------------------------

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

System.out.println(scores.length);  // 2
System.out.println(scores[0].length); // 2
System.out.println(scores[1].length); // 3

//--------------------------------------------
// 다차원 배열 초기화

int[][] scores = { {95, 80}, {92, 96} };

System.out.println( scores[0][0] ); // 95
System.out.println( scores[1][1] ); // 96

int[][] javaScores = { {95, 80}, {92, 96, 80} };

for(int i = 0; i < javaScores.length; i++) {
    for(int k = 0; k < javaScores[i].length; k++) {
        System.out.println( javaScores[i][k] );
    }
}

배열 복사

  • 예제 코드
public class ArrayCopyExample {
    public static void main(String[] args) {
        // for 문 이용

        int[] oldIntArray = { 1, 2, 3 };
        int[] newIntArray = new int[5];

        for(int i = 0; i < oldIntArray.length; i++)
            newIntArray[i] = oldIntArray[i];

        for(int i = 0; i < newIntArray.length; i++)
            System.out.print(newIntArray[i] + "," );

        System.out.println();

        // arraycopy 이용
        String[] oldStrArray = { "java", "array", "copy" };
        String[] newStrArray = new String[5];

        System.arraycopy(oldStrArray, 0, newStrArray, 0, oldIntArray.length); // p.169 그림 참조

        for(int i = 0; i < newStrArray.length; i++)
            System.out.print(newStrArray[i] + ", ");

        System.out.println();
    }
}
  • 실행 결과
1,2,3,0,0,
java, array, copy, null, null,

향상된 for 문

public class ArrayCopyExample {
    public static void main(String[] args) {
        // for 문 이용

        int[] oldIntArray = { 1, 2, 3 };
        int[] newIntArray = new int[5];

        for(int i = 0; i < oldIntArray.length; i++)
            newIntArray[i] = oldIntArray[i];

        for(int value : newIntArray) // ← 배열 전체를 스캔하는데 인덱스가 필요없음
            System.out.print(value + "," );
        System.out.println();

        // arraycopy 이용
        String[] oldStrArray = { "java", "array", "copy" };
        String[] newStrArray = new String[5];

        System.arraycopy(oldStrArray, 0, newStrArray, 0, oldIntArray.length);

        for(String str : newStrArray) // ← 배열 전체를 스캔하는데 인덱스가 필요없음
            System.out.print(str + ", ");
        System.out.println();
    }
}

열거 타입(Enumeration Type)

  • Java에서 이름 짓는 법
종류 설명
변수 name 소문자를 이용하여 짓는다. 영어가 아닌 한국어로 변수 이름을 지어도 되지만 관례적으로 로마자를 사용한다.
myName, myFirstName 두 개의 단어가 연이어 나오면 새로운 단어의 시작은 대문자로 한다.
메소드 move() 소문자로 짓는다. 이름 뒤에 연이어 괄호가 나오기 때문에 이름으로 변수와 메소드를 구분할 수 있다.
moveLeft() 두 개의 단어가 연이어 나오면 새로운 단어의 시작은 대문자로 한다.
클래스, 인터페이스, 열거형 Car 시작 문자를 대문자로 한다.
BlueCar 두 개의 단어가 연이어 나오면 새로운 단어의 시작은 대문자로 한다.
상수(static final) COLOR 모든 문자를 대문자로 한다.
BLUE_COLOR 두 개의 단어가 연이어 나오면 단어 사이에 _를 붙인다.

열거 타입 선언

  • 상수를 여러 개 만들고 싶을 때
public enum Week { MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY };

public enum LoginResult { LOGIN_SUCCESS, LOGIN_FAILED };

Week today;
Week reservationDay;
Week birthday = null;

today = Week.SUNDAY;

if (today == Week.SUNDAY) { // true
  • Calendar 객체를 이용한 열거형 연습
Calendar now = Calendar.getInstance();

int year = now.get(Calendar.YEAR); // 년
int month = now.get(Calendar.MONTH) + 1; // 월
int day = now.get(Calendar.DAY_OF_MONTH); // 일
int week = now.get(Calendar.DAY_OF_WEEK); // 요일 (1~7)
int hour = now.get(Calendar.HOUR); // 시간 
int minute = now.get(Calendar.MINUTE); // 분
int second = now.get(Calendar.SECOND); // 초

열거 객체의 메소드

  • 열거 객체는 java.lang.Enum 클래스로부터 상속받음.
리턴 타입 메소드(매개 변수) 설명
String name() 열거 객체의 문자열을 리턴
int ordinal() 열거 객체의 순번(0부터 시작)을 리턴
int compareTo() 열거 객체를 비교하여 순번 차이를 리턴
열거 타입 valueOf(String name) 주어진 문자열의 열거 객체를 리턴
열거 배열 values() 모든 열거 객체들을 배열로 리턴

Week today = Week.SUNDAY;

String name = today.name(); // "SUNDAY"

int ordinal = today.ordinal(); // 6. 0부터 시작하여 6번째 데이터라는 뜻임

Week day1 = Week.MONDAY;
Week day2 = Week.WEDNESDAY;

int result1 = day1.compareTo(day2); // -2 (0 - 2)
int result2 = day2.compareTo(day1); // 2 (2 - 0)

Week weekDay = Week.valueOf("SATURDAY"); // Week.SATURDAY

Week[] days = Week.values();
for(Week day : days)
    System.out.println(day);