참조타입

woom·2022년 10월 28일
0

JAVA

목록 보기
6/18
post-thumbnail

🌼 메모리 영역

  • 프로그램에서 사용하는 메모리 영역
    1. 정적영역(Static Area) : 클래스 파일(XXX.class)의 Java 자료형(클래스, 인터페이스 등)을 읽어 저장하는 메모리 영역
      → 식별자를 이용해 고유한 이름 저장
    1. 힙영역(Heap Area) : 배열 및 객체가 저장되는 메모리 영역으로 new 연산자 사용
      → 메모리에 이름 설정 불가능(메모리에 접근할 수 있는 방법 없음) → 참조변수(메모리에 접근할수 있는 주소 저장) 필요
      → 즉, 참조변수는 힙영역에 생성된 배열 또는 객체의 메모리 주소를 힙메모리에 저장하여 접근하기 위해 사용
      → 가장큰 메모리 영역을 가지고 있음, 메모리 할당과 제거 가능 즉 메모리 효율성 좋음
    1. 스택영역(Stack Area) : 지역변수(기본변수 또는 참조변수)가 저장되는 메모리 영역 (선언된 블럭이 끝나면 소멸된다)
      → 메모리 용량이 작기 때문에 모든 변수를 만들 수 없어, FILO(First In Last Out)
  • garbage collector에 의해 특정 시점에 정적 영역과 힙 영역이 청소된다 따라서 메모리 정리 하지 않음
     

📌 자료형(DataType)

    1. 원시형 : 값을 표현하기 위한 자료형 - byte, short, int, long, char, float, double, boolean
    1. 참조형 : 특정 대상을 표현하기 위한 자료형 - 배열(Array), 클래스(Class), 인터페이스(Interface), 열거형(Enum)

📌 변수

    1. 기본변수 : 원시형으로 생성된 변수로 값을 저장하기 위한 변수 ex) int num=10;
    1. 참조변수 : 참조형으로 생성된 변수로 특정 대상의 메모리 주소값을 저장하기 위한 변수
      (값을 하나밖에 저장 못함) ex) String name="홍길동";
    • 힙영역에 생성된 배열 또는 객체의 메모리 주소를 저장하여 접근하기 위해 사용
    • 참조변수는 비교연산자를 사용할 경우 메모리 주소 비교/ but 잘 사용하지 않음 의미 없음
    • 참조변수에 배열 또는 객체를 저장하지 않을 경우 기본값으로 null (존재하지 않는 값을 표현하는 키워드) 저장

🌼 Array (배열)

  • 같은 자료형의 값을 여러개 저장하기 위한 메모리을 할당받기 위한 자료형 (참조형)

  • 일괄처리(통계, 다수의 값이 필요한 경우)를 목적으로 사용하기 위한 자료형

  • 1차원 배열과 다차원 배열(2차원 배열, 3차원 배열 등)로 구분
    • 1차원 배열 : 다수의 값을 저장하기 위한 자료형
    • 다차원 배열 : 다수의 배열을 저장하기 위한 자료형

📙 1차원배열

  • 1차원 배열을 생성하여 참조변수에 생성된 배열의 메모리 주소(HashCode)를 저장
  • 1차원 배열은 다수의 값을 저장하기 위한 요소(Element)의 모임 ex) 0번지 요소, 1번지 요소, ··· , n번지 요소
    • 배열의 요소는 첨자(index)를 이용하여 구분
    • Index : 0부터 1씩 증가되는 정수값 (예외적으로 오라클에서 사용되는 sql의 인덱스는 1부터 증가)
  • 생성된 배열의 요소에는 기본값( 논리형:false, 숫자형:0, 참조형:null )이 초기값으로 자동 저장
  • 형식) 자료형[ ] 참조변수=new 자료형[갯수]; // [ ] : 1차원 배열 자료형
    • ex) int[ ] num=new int[3];
      : 참조변수 num에 정수형(int)의 3가지 요소를 가지고 있는 1차원 배열의 메모리 주소를 저장하겠다.
    • new 자료형[갯수] : 자료형의 값을 갯수만큼 저장 가능한 배열 생성 (힙메모리에 저장)
    • 자료형[ ] 참조변수 : 1차원 배열의 메모리 주소를 저장하기 위한 참조변수 생성
    • "자료형 참조변수[ ]" 형식으로 참조변수 생성 가능하나 잘 사용하지 않음

🐣 예제

public class ArrayApp {
	public static void main(String[] args) {
		int[] num=new int[3];
		//참조변수에 저장된 값은 "자료형@메모리주소" 형식으로 제공받아 출력
		System.out.println("num = "+num);
		

		//참조변수와 배열의 요소를 구분하는 첨자를 사용하여 배열 요소에 접근하여 사용
		//형식)참조변수[첨자] - 배열의 요소를 표현하는 방법
		System.out.println("num[0] = "+num[0]); //요소값 출력 (숫자형 초기값 : 0)
		System.out.println("num[1] = "+num[1]); //num이라는 참조변수가 갖는 1번지 요소 값
		System.out.println("num[2] = "+num[2]);//0
		//요소를 구분하는 첨자를 잘못 사용한경우 ArrayIndexOutOfBoundsException 예외 발생
		// => 예외(Exception)가 발생된 경우 프로그램 강제 종료
		

		//참조변수.length : 참조변수에 저장된 배열 요소의 갯수를 표현하는 방법
		System.out.println("배열 요소의 갯수 = "+num.length);//3
		

		int index=0;
		//배열 요소를 구분하는 첨자는 변수 또는 연산식으로 표현 가능
		num[index]=10;//요소값 변경 (넘이라는 참조변수가 가르키는 0번지 요소에 10을 저장해라)
		num[index+1]=20;
		num[index+2]=30;
		
		//for구문을 사용하여 배열 요소에 대한 일괄 처리(입력,계산,출력에 대한 일괄처리에 사용)
		//for 구문의 초기식,조건식,증감식에서 사용하는 변수로 첨자를 표현하여 일괄 처리
		for(int i=0;i<num.length;i++) {
			System.out.println("num["+i+"] = "+num[i]);
		}//num[0]=10, num[1]=20, num[2]=30
		
        
        
  • 배열 생성시 배열 요소에 기본값 대신 원하는 초기값 저장 가능
  • 형식1. 자료형[ ] 참조변수=new 자료형[] {초기값, 초기값, ... };
    • 일반형으로 힙메모리에 생성됨
    • 블럭({ }) 안에 나열된 초기값의 갯수만큼의 요소를 가지고 있는 배열 생성 ([]안에 작성X)
  • 형식2. 자료형[ ] 참조변수={초기값, 초기값, ... };
    • 간편형으로 상수영역(정적과 힙중간)에 생성됨
    • 참조변수 미리 생성한 후 배열을 생성하여 저장 불가능




public class ArrayApp {
	public static void main(String[] args) {
    	//형식1
		int[] su1;
		su1=new int[] {10,20,30};
		
		for(int i=0;i<su1.length;i++) {
			System.out.println("su1["+i+"] = "+su1[i]);
		}

		//형식2
		int[] su2={10,20,30};
        
   
   
  • 배열을 일괄처리하기 위한 변형된 for 구문 형식
  • for (자료형 변수명:참조변수) { 명령; 명령; ... }
  • 참조변수에 저장된 배열의 요소값을 커서를 사용하여 차례대로 제공받아 변수에 저장하여 반복 처리
    • 배열의 모든 요소값을 제공받은 후 반복문 종료
    • 계산, 출력에 대한 일괄처리에 사용
      (요소를 접근하는 것이 아니라 제공하는 것이기 때문에 입력에 대한 일괄처리 불가)


public class ArrayApp {
	public static void main(String[] args) {        
		for(int temp:su2) {
			System.out.println(temp);
		}
		

		//배열의 모든 요소들의 값에 대한 합계를 계산하여 출력
		int[] array={54,70,64,87,96,21,65,76,11,34,56,41,77,80};
		int tot=0;
		for(int i=0;i<array.length;i++) {
			tot+=array[i];
		}
		System.out.println("합계 = "+tot);
		

		//배열의 요소값이 30~60 범위의 정수값인 요소의 갯수를 계산하여 출력
		int count=0;
		for(int element:array) {
			if(element>=30 && element<=60) {
				count++;}}
		
		System.out.println("30~60 범위의 요소 갯수 = "+count);
        
        
        

📙 다차원 배열

  • 다차원 배열 : 배열의 모임 / 2차원 배열 : 1차원 배열의 모임
  • 형식) 자료형[][] 참조변수 = new 자료형 [행갯수][열갯수];
    • 행갯수: 2차원 배열에 저장되는 1차원 배열의 갯수
    • 열갯수 : 1차원 배열에 저장되는 요소의 갯수

🐣 예제

		int[][] num=new int[2][3];
		
		System.out.println("num = "+num);    		  // 메모리 주소값 출력 (해시코드)
		System.out.println("num[0] = "+num[0]); 	  // 1차원배열의 메모리 주소
		System.out.println("num[1] = "+num[1]);
		
        
		System.out.println("num[0][0] = "+num[0][0]); // 요소들의 초기값 : 모두 0
		System.out.println("num[0][1] = "+num[0][1]);
		System.out.println("num[0][2] = "+num[0][2]);

		System.out.println("num[1][0] = "+num[1][0]);
		System.out.println("num[1][1] = "+num[1][1]);
		System.out.println("num[1][2] = "+num[1][2]);
		

		System.out.println("num.length = "+num.length);	//1차원 배열의 갯수:2
		System.out.println("num[0].length = "+num[0].length);//1차원 배열의 요소 갯수:3
		System.out.println("num[1].length = "+num[1].length);
		

		for(int i=0;i<num.length;i++) {//행처리 : 1차원 배열의 갯수만큼 반복 처리
			for(int j=0;j<num[i].length;j++) {//열처리:1차원 배열의 요소 갯수만큼 반복처리
				System.out.print(num[i][j]+"  ");
			}
			System.out.println();
		}
		
        

		//int[][] su=new int[][] {{10,20,30},{40,50,60},{70,80,90}};
		int[][] su={{10,20,30},{40,50,60},{70,80,90}};
		
		for(int[] array:su) {
			for(int number:array) {
				System.out.print(number+"  ");
			}
			System.out.println();
		}
		
        

		//1차원 배열이 없는 2차원 배열 생성
		// => 1차원 배열의 메모리 주소를 저장할 수 있는 참조요소만 생성
		// => 2차원의 배열의 참조요소에는 null 저장
		int[][] value=new int[3][];
		
		System.out.println("value = "+value);
		System.out.println("value[0] = "+value[0]);
		System.out.println("value[1] = "+value[1]);
		System.out.println("value[2] = "+value[2]);
		
        

		//2차원 배열의 참조요소에 1차원 배열을 생성하여 저장
		// => 1차원 배열의 요소의 갯수를 다르게 생성하여 저장 가능 - 가변배열
		value[0]=new int[3];
		value[1]=new int[2];
		value[2]=new int[4];
		
		System.out.println("value[0] = "+value[0]);
		System.out.println("value[1] = "+value[1]);
		System.out.println("value[2] = "+value[2]);
		
        

		//가변배열 : 1차원 배열에 저장되는 요수의 갯수가 틀린 경우
		int[][] doubleArray={{10,20,30},{40,50},{60,70,80,90}};
		
		for(int[] array:doubleArray) {
			for(int number:array) {
				System.out.print(number+"  ");
			}
			System.out.println();





🎀 연습문제1 - Lotto

  • 1~45 범위의 난수를 6개 제공받아 출력하는 프로그램 (6개 난수는 서로 중복되지 않도록 작성, 오름차순 정렬하여 출력)
    • 정렬(Sort) : 값을 순서대로 나열하는 기능
    • 오름차순 정렬(AscendingSort), 내림차순 정렬(DescendingSort)


public class LottoApp {
	public static void main(String[] args) {
		//6개의 정수 난수를 저장하기 위한 배열 선언
		int[] lotto=new int[6];
		
		//1~45 범위의 정수난수를 6개 제공받아 배열 요소에 차례대로 저장
		// => 중복된 난수값이 아닌 경우에만 배열 요소에 저장
		for(int i=0;i<lotto.length;i++) {//새로운 난수값을 저장하는 배열 요소의 첨자 표현
			//요소에 저장된 새로운 난수값을 기존 요소의 난수값과 모두 비교하여 같은 값이 있는
			//반복문을 이용하여 새로운 난수값을 제공받아 배열 요소에 저장
			// => 새로운 난수값이 기존 요소의 난수값과 다른 경우 반복문 종료
			while(true) {//정상적인 값이 입력된 경우 반복문 종료 - 입력값 검증
				//1~45범위의 난수를 제공받아 배열 요소에 저장
				lotto[i]=(int)(Math.random()*45)+1;
					
				//중복상태를 저장하기 위한 변수
				// => false : 미중복, true : 중복
				boolean result=false;
				
				//새로운 난수값을 기존 배열 요소의 난수값과 비교
				for(int j=0;j<i;j++) {//기존 난수값이 저장된 배열 요소의 첨자 표현 
					if(lotto[i]==lotto[j]) {
                    //lotto[i] : 새로운 난수값, lotto[j] : 기존 난수값
						result=true;
						break;}}
				
				//새로운 난수값이 기존 난수값과 비교하여 중복되지 않은 경우 반복문 종료
				if(!result) break;}}
		
		//배열의 모든 요소값을 서로 비교하여 오름차순 정렬되도록 배열 요소값을 바꾸어 저장
		// => 선택 정렬 알고리즘(Selection Sorting Algorithm) 사용
		for(int i=0;i<lotto.length-1;i++) {//비교 요소의 첨자 표현 : 처음 ~ 끝-1
			for(int j=i+1;j<lotto.length;j++) {//피비교 요소의 첨자 표현 : 비교+1 ~ 끝
				if(lotto[i]>lotto[j]) {//lotto[i] : 비교 요소, lotto[j] : 피비교 요소
					//비교한 요소의 값을 서로 바꾸어 저장
					int temp=lotto[i];
					lotto[i]=lotto[j];
					lotto[j]=temp;}}}
		
		//배열의 모든 요소값 출력
		System.out.print("행운의 숫자 >> ");
		for(int number:lotto) {
			System.out.print(number+" ");}
		System.out.println();}}
        
        
        
        

🎀 연습문제2 - 구구단

  • 키보드로 정수값을 입력받아 1~9 범위의 정수값을 곱한 결과를 출력하는 프로그램을 작성하세요.
  • 단, 키보드로 입력된 정수값은 2~9 범위의 정수값만 허용하며 범위를 벗어난 정수값을 입력한 경우 에러 메세지 출력 후 재입력하도록 프로그램 작성
    ex) 단 입력[2~9] >> 7
    7 1 = 7
    ...
    7
    9 = 63


public class GuGuDanExample {
	public static void main(String[] args) {
		Scanner scanner=new Scanner(System.in);
		
		int dan;
		while(true) {//입력값 검증을 위한 반복문
			System.out.print("단 입력[2~9] >> ");
			dan=scanner.nextInt();
			if(dan>=2 && dan<=9) break;//정상적인 입력값인 경우 반복문 종료
			//비정상적인 입력값인 경우 에러메세지 출력 >> 반복문 재실행
			System.out.println("[에러]2~9 범위의 정수값만 입력 가능합니다.");
		}
		
		for(int i=1;i<=9;i++) {
			System.out.println(dan+" * "+i+" = "+(dan*i));
		}
		
		scanner.close();





🎀 연습문제3 - UpAndDown

  • 컴퓨터로부터 제공받은 정수 난수값을 키보드로 입력하여 맞추는 프로그램을 작성하세요.
    • 1~100 범위의 정수 난수값을 제공받도록 작성
    • 난수값을 맞출 수 있는 기회는 10번만 제공되도록 작성
    • 키보드 입력값이 1~100 범위가 아닌 경우 메세지 출력 후 재입력
    • 난수값과 입력값이 같은 경우 입력 횟수 출력 후 프로그램 종료
    • 난수값과 입력값이 다른 경우 "큰값 입력" 또는 "작은값 입력" 형식의 메세지 출력
    • 난수값을 10번 안에 맞추지 못한 경우 난수값이 출력되도록 작성


public class UpAndDownExample {
	public static void main(String[] args) {
		Scanner scanner=new Scanner(System.in);
		
		//1~100 범위의 정수난수를 제공받아 변수에 저장
		int dap=(int)(Math.random()*100)+1;
		
		//정답 상태를 저장하기 위한 변수
		// => false : 정답을 맞추지 못한 상태, true : 정답을 맞춘 상태
		boolean result=false;   // 초기값 false
		
		//10번의 기회를 제공하기 위한 반복문
		// => 키보드로 정수값을 입력받아 난수값과 비교하여 결과 출력
		for(int i=1;i<=10;i++) {
			//키보드로 1~100 범위의 정수값을 입력받아 저장
			// => 비정상적인 값이 입력된 경우 재입력 처리
			int input;
			while(true) {//키보드 입력값을 검증하는 반복문
				System.out.print(i+"번째 정수값 입력[1~100] >> ");
				input=scanner.nextInt();
				if(input>=1 && input<=100) break;
				System.out.println("[에러]1~100 범위의 정수값만 입력해 주세요.");
			}
			
			//난수값과 입력값을 비교하여 결과 출력
			if(dap==input) {//난수값과 입력값이 같은 경우
				System.out.println("[메세지]축하합니다."+i+"번만에 맞췄습니다.");
				result=true;    //정답을 맞췄을 때
				break;//반복문 종료 >> 프로그램 종료
			} else if(dap>input) {//난수값이 입력값보다 큰 경우
				System.out.println("[결과]"+input+"보다 큰 값을 입력해 보세요.");
			} else {//난수값이 입력값보다 작은 경우
				System.out.println("[결과]"+input+"보다 작은 값을 입력해 보세요.");
			}
		}
		
		if(!result) {//정답을 맞추지 못한 경우
			System.out.println("[메세지]정답을 맞추지 못했군요. 정답은 ["+dap+"]입니다.");
		}
		
		scanner.close();





🎀 연습문제4 - 배열

public class ArrayExample {
	public static void main(String[] args) {
		//사람들의 나이를 저장한 배열 생성하여 참조변수에 저장		
		int[] age={27,16,22,36,57,60,43,23,14,29,44,52,59,51,39,33,11};
		
		//1.배열에 저장된 모든 사람들의 나이 평균을 계산하여 출력하세요.
		int tot=0;
		for(int nai:age) {
			tot+=nai;
		}
		
		System.out.println("평균 나이 = "+(tot/age.length)+"살");
		

		//2.배열에 저장된 사람들의 나이를 연령별로 구분하여 인원수를 계산하여 출력하세요.
		//ex) 10대 = 3명
		//    20대 = 4명
		//    ...
		//    60대 = 1명
        
		//첫번째방법
		int cnt10=0, cnt20=0, cnt30=0, cnt40=0, cnt50=0, cnt60=0;
		
		for(int nai:age) {
			if(nai>=10 && nai<=19) cnt10++;
			else if(nai>=20 && nai<=29) cnt20++;
			else if(nai>=30 && nai<=39) cnt30++;
			else if(nai>=40 && nai<=49) cnt40++;
			else if(nai>=50 && nai<=59) cnt50++;
			else if(nai>=60 && nai<=69) cnt60++;
		}
		
		System.out.println("10대 = "+cnt10+"명");
		System.out.println("20대 = "+cnt20+"명");
		System.out.println("30대 = "+cnt30+"명");
		System.out.println("40대 = "+cnt40+"명");
		System.out.println("50대 = "+cnt50+"명");
		System.out.println("60대 = "+cnt60+"명");
		
		//두번째방법
		int[] cnt=new int[6];//연령별 인원수를 저장하기 위한 배열 생성
		
		for(int nai:age) {
			/*
			if(nai>=10 && nai<=19) cnt[0]++;
			else if(nai>=20 && nai<=29) cnt[1]++;
			else if(nai>=30 && nai<=39) cnt[2]++;
			else if(nai>=40 && nai<=49) cnt[3]++;
			else if(nai>=50 && nai<=59) cnt[4]++;
			else if(nai>=60 && nai<=69) cnt[5]++;
			*/
			
			/*
			switch (nai/10) {
			case 1: cnt[0]++; break;
			case 2: cnt[1]++; break;
			case 3: cnt[2]++; break;
			case 4: cnt[3]++; break;
			case 5: cnt[4]++; break;
			case 6: cnt[5]++; break;
			}
			*/
			
			cnt[nai/10-1]++;
		}
		
		for(int i=0;i<cnt.length;i++) {
			System.out.println((i+1)*10+"대 = "+cnt[i]+"명");
		}	
        
        
        
        

profile
Study Log 📂

0개의 댓글

관련 채용 정보