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

From DISLab
Jump to navigation Jump to search
Line 386: Line 386:
             newIntArray[i] = oldIntArray[i];
             newIntArray[i] = oldIntArray[i];


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


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

Revision as of 16:00, 20 July 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 문

package ch05;

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();
    }
}

열거 타입