ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Java] 배열, 향상된 for문
    언어/Java 2024. 10. 28. 12:20

    https://www.inflearn.com/course/%EA%B9%80%EC%98%81%ED%95%9C%EC%9D%98-%EC%9E%90%EB%B0%94-%EC%9E%85%EB%AC%B8/dashboard

     

    [지금 무료]김영한의 자바 입문 - 코드로 시작하는 자바 첫걸음 강의 | 김영한 - 인프런

    김영한 | 프로그래밍에 처음 입문하는 분들을 위한 자바 강의입니다. 코드를 따라하면서 손쉽게 자바를 배울 수 있습니다., 국내 개발 분야 누적 수강생 1위, 제대로 만든 김영한의 자바 입문[사

    www.inflearn.com

    아래 내용의 출저는 위 강의에서 가지고 왔으며, 더욱 자세하게 보실 수 있습니다. 

    오늘의 단축키 Tip
    향상된 for문을 사용하고 싶을 때 
    iter

    섹션 8 - 문제와 풀이 4

    package scanner.ex;
    
    import java.util.Scanner;
    
    public class ScannerWhileEx3 {
    
        public static void main(String[] args) {
            Scanner input = new Scanner(System.in);
            int sum = 0;
            int cnt = 0;
            int num = 0;
            System.out.print("숫자를 입력하세요. 입력을 중단하려면 -1을 입력하세요 : ");
            while ((num = input.nextInt()) != -1) {
                cnt++;
                sum += num;
            }
    
            System.out.println("입력한 숫자들의 합계 : " + sum);
            System.out.println("입력한 숫자들의 평균 : " + (double)sum / cnt);
    
        }
    }
    • 위 소스 코드에서 while문을 원래 배운 대로 라면 아래와 같다.
    while (true) {
    	if (num == -1){
        	break;
        }
    }
    • 위 코드를 간결하게 while ((num = input.nextInt()) != -1) 로 바꾸어 줄 수 있다. 즉, 축약이 가능하다. 

    배열  

    int[] students;
    • int a; 에는 int 형 변수를 담을 수 있는 것 처럼
    • int[] students 도 int 배열을 students 에 담을 수 있다.
    • 이 때 students는 배열을 가리키는 참조값을 생성한다.
    • 이 때는 참조 변수만큼만 메모리에 공간을 차지한다. 32JVM 에서는 4바이트 64JVM 에서는 8바이트
      • 주소 공간
        • 32비트 시스템 : 메모리 주소를 32비트로 표현 하므로 2**32 (약 4GB)의 메모리 주소를 사용할 수 있다.
        • 64비트 시스템 : 2**64 메모리의 주소를 사용할 수 있다. 
      • 참조 변수의 크기
        • 32 비트 시스템 : 참조 변수의 크기는 4바이트. 즉, 배열이나 객체의 주소를 4바이트로 저장한다. 
          • PT형 말로는 그 크기를 직접 확인하고 싶은 데 그럴 수는 없다고 한다. 
    students = new int[5];
    int[] students = new int[5]; // 배열 생성
    int[] students = x001; // new int[5]의 결과로 x001 참조값 반환

    • 총 5개의 int 형 변수를 생성한다. 
    • 자바는 배열을 생성할 때, 그 내부값을 자동으로 초기화 한다. 
    • int형은 0
    • String은 null
    • boolean 은 false
    • new int[5] 자체에는 아무런 이름이 없다. 다시 말해 연속적으로 5개의 공간만 비워둔 상태
    • 따라서 생성한 배열에 접근하는 방법이 필요하다. 
    • 배열을 생성할 때 참조값을 어딘가에 보관해두어야 한다.
    • 여기서는 `students 라는 변수를 통해 이 배열에 접근할 수 있다. 
    • 동적으로 어떻게 넣어줄까?
    int[] students = new int[5]; // 배열 생성
    int[] students = x001; // new int[5]의 결과로 x001 참조값 반환

    1차원 배열 리팩토링 

    int[] students = new int[]{90. 80, 70, 60, 50};
    // 위 소스 코드와 아래는 같다.
    int[] students = {90, 80,30, 60, 50};
    • 주의할 점은 선언과 동시에 초기화를 해야 작동한다. 그 이유는 new 키워드 없이 배열을 직접 할당하는 것은 문법적으로 올바르지 않아서 컴파일 오류가 발생한다.

    2차원 배열

    int[][] arr = new int[2][3];
    
    arr[행][열], arr[row][clomun]
    • 번외
      • 2차원 배열에서는 2중 for문으로 2차원 배열에 접근할 때, 
      • 열 우선 접근 보다 행 우선 접근을 해야 한다.
      • 예를 들어
    1 2 3
    4 5 6
    • 위와 같은 2차원 배열이 있다고 하자. 
    • 메모리상에는 아래와 같이 저장될 것이다.
    | 1 | 2 | 3 | 4 | 5 | 6 |
    • 열 우선 접근을 하게 된다면,  메모리의 비연속적인 위치에 접근하게 된다. 이 경우 캐시의 효율성이 떨어진다.
    • 따라서 행 우선 접근을 해서 첫 번째 루프(행)을 통해 모든 열에 접근하고, (연속적), 나서 다음 행으로 넘어가기 때문에 메모리 캐시 히트가 높아진다. (지역성의 원리 - 공간 지역성이 좋은 예제)
    package array;
    
    public class ArrayDi3 {
    
        public static void main(String[] args) {
            // 2x3 2차원 배열을 만든다.
            int[][] arr = {
                {1,2,3},
                {4,5,6}
            }; //행2, 열3
    
            for (int row = 0; row < arr.length; row++) {
                for (int column = 0; column < arr[row].length; column++) {
                    System.out.print(arr[row][column] + " ");
                }
                System.out.println();//한 행이 끝나면 라인을 변경한다.
            }
        }
    }
    • arr.length -> 제일 밖에 있는 괄호 안에 괄호들이 몇개 있는 지 { {}, {} } 2개 있다. 
    • arr[row].length -> 그 안에 있는 괄호들 안에 원소가 몇개 있는 지 { {1, 2, 3}, {4, 5, 6} } -> 3개

    [일반적인 for문]

    for (int i = 0; i < numbers.length; i++) {
                int number = numbers[i];
                System.out.println(number);
            }
    • 배열에 있는 값을 순서대로 읽어서 number 변수에 넣고 출력한다. 
    • 배열은 처음부터 끝까지 순서대로 읽어서 사용하는 경우가 많다.
    • 그런데 배열의 값을 읽으려만 int i 와 같은 인덱스를 사용해 탐색할 수 있는 변수를 선언해야 한다.
    • 그리고 끝 조건을 지정해야 한다.
    • 마지막으로 배열의 값을 하나 읽을 때마다 인덱스를 하나씩 증가해야 한다.

    [향상된 for문 -  for-each]

    for (number : numbers) {
    	sout(number);
    }
    • 실무에서 가장 많이 사용하는 for문
    • 단순히 해당 배열을 처음부터 끝까지 탐색한다. 
    • for(반복할 때마다 찾은 값을 저장할 변수 : 배열) 
    • 그러면 알아서 numbers[i] 에 값들이 저장된다 !!!!! 
    • 주의 할점 ! 
      • 인덱스 값이 필요할 때는 당연히 사용할 수 없다. 

    [문제와 풀이 1 ArrEx2]

    public static void main(String[] args) {
            Scanner scanner = new Scanner(System.in);
            System.out.println("5개의 정수를 입력하세요:");
            int[] arr = new int[5];
    
            for (int i = 0; i < arr.length; i++) {
                 arr[i] = scanner.nextInt();
            }
    
            System.out.println("출력");
            for (int i = 0; i < arr.length; i++) {
                System.out.print(arr[i]);
                if (i < arr.length - 1) {
                    System.out.print(", ");
                }
            }
        }
    • 첫 번째 for문에서 arr = scanner.nextInt(); 라고 작성하였다.
    • 값을 인덱스에 넣어줄 거기 때문에 arr[i] = scanner.nextInt(); 해주는 게 맞다. 

    향상된 for문으로 값 넣기는 안된다. 

    int[] numbers = new int[5];
                for (int number : numbers) {
                    number = nextInt();
                }

    • for-each (향상된 for문)에서 사용되는 변수가 배열의 요소를 참조하는 것이 아니라, 각 요소의 복사본을 다루기 때문이다.
    • 위 소스코드에서 number는 numbers 배열의 각 요소의 복사본이다. 즉, number를 변경해도 numbers 배열의 값은 변경되지 않는다.
    • 따라서 인덱스를 사용하여 직접 접근해 수정해야 된다. 

    숫자 사이에 ', ' 넣기 

    if (i < arr.length - 1){
    	sout(', );
    }

     

    베열과 역순 출력

    public static void main(String[] args) {
            Scanner scanner = new Scanner(System.in);
    
            int[] arr = new int[5];
    
            System.out.println("5개의 정수를 입력하세요: ");
            for (int i = 0; i < arr.length; i++) {
                arr[i] = scanner.nextInt();
            }
    
            for (int i = arr.length; i < 0; i--) {
                System.out.println(arr[i]);
            }
        }

    출력 결과

    • intelJ 에서 돌렸을 때 딱히 컴파일은 잘된다. 
    • 하지만 내가 원한 의도와 다르게 결과값을 출력하는 것을 볼 수 있다. 

    생각 1

    for(int i = arr.length ...)
    • arr.len은 현재 5이고 arr의 마지막 인덱스는 4이다. 이 부분에서 인식하지 못해 생긴 오류라고 생각이 든다.
    • 따라서 arr.len - 1을 해주었다. 
    for(int i = arr.length - 1; i < 0; i++)
    • 어랏 그래도 출력되지 않았다.

    생각 2

    for(int i = arr.length; i < 0; i--)
    • 위 소스 코드에서 i < 0; 이 잘못되었구나. i는 5, 4, 3,........점진적으로 작아질 텐데... for문이 안끝나겠구나.
    • i >= 0 로 종료 조건을 바꾸어 주었더니 해결했다. 

     

Designed by Tistory.