상수형 변수가 필요한 경우

 

방향을 표현하고 싶은 변수가 있다고 가정해 보자.

 

4번 방향으로 가고 싶으면 다음과 같이 표시할 것이다.

int direction; direction = 4; direction = SE;


만약 위 사진이 없다면 4번 방향이 어딘지 모를 것이다.

int N = 1;		N(1);
int NE = 2;		NE(2);
int E = 3;		E(3);
int SE = 4;		SE(4);
int S = 5;		S(5);
int SW = 6;		SW(6);
int W = 7;		W(7);
int NW = 8;		NW(8);

 

위에 있는 값들은 고정적으로 사용할 값들이어서 바뀌면 안 된다.

 

변수가 바뀌지 않게 앞에 "final"을 붙여주면 된다. 이를 상수형 변수이다.

final int N = 1;		N(1);
final int NE = 2;		NE(2);
final int E = 3;		E(3);
final int SE = 4;		SE(4);
final int S = 5;		S(5);
final int SW = 6;		SW(6);
final int W = 7;		W(7);
final int NW = 8;		NW(8);

변수의 생명주기

프로그램을 실행시키면 text에 올라간다. 

 

Data영역heap영역 stack영역으로 나눠진다. (전역 데이터를 관리하는 공간) 

 

stack영역에 준비물 args, total, avg, kors (보라색은 참조변수, 초록색은 일반변수) 블록 들어가기 전에 예약석에 넣은 느낌이다. 그리고 자물쇠로 봉인.

 

참조변수 같은 경우는 주소값을 미리 부여받고 봉인! 바꿀수 없으니까 다른 메모리 영역(heap)에 저장하는것이다.

 

딱 stack이랑 heap이 나눠지는 게 아니고 stack을 할당하고 나머지 공간이 heap이 되는 것이다.

 

감시컬랙터(가비지 컬렉터)는 cpu가 한가할 때 쓰레기를 수거해 간다. 가비지는 heap에만 있다. 또 메모리가 부족한 경우가 오면 가비지 컬렉터가 또 돌아가긴 한다.

 


오류

  • 구문오류(컴파일러가 잡아준다.)
x=3;
3=x;

 

  • 논문오류(치명적)
total/5; (총 3명인데 5로 나눔)
//결과가 5.77..이렇게 만들어야하는데 정수로 나눠서 정수로만 값이 나옴

 

디버거를 사용해서 오류를 잡을 수  있다.

 

 


자바의 다차원 배열과 톱니형 배열

 

//lotto 번호를 저장하기 위한 1차원 배열
int[] lotto = new int[6];

하나의 번호만 저장할 수 있다.

 

//lotto 번호를 저장하기 위한 다차원 배열
int[][] lotto = new int[3][6];

3가지의 로또번호를 저장할 수 있다.

 

자바에서는 아래 그림처럼 다차원배열이 구성되어 있다.

배열을 바꾸고 싶으면 새로운 배열에 옮겨주면 된다.

 

public class Program {
    public static void main(String[] args) {
        //int[][] lottos=new int[3][6];
        //int[][] lottos=new int[3][6]{{1,2,3,4,5,6},{7,8,9,10,11,12},{13,14,15,16,17,18}};
        int[][] lottos={{1,2,3,4,5,6},{7,8,9,10,11,12},{13,14,15,16,17,18}};

        for(int i=0;i<3;i++) {
            for (int j = 0; j < 6; j++)
                System.out.printf("%4d, ",lottos[i][j]);

            System.out.println();
        }
        System.out.println("------ 0<->2 위치 변경 --------");

        int[] temp = lottos[0];
        lottos[0]=lottos[2];
        lottos[2]=temp;
        /*
        [1] <-> [2]

        lottos         ->2차 배열의 이름
        lottos[0]      ->1차 배열의 이름
        lottos[0][0]   ->정수 변수의 이름

        int x = lottos[0][0];     값 변수는 값을 대입하는 연산이 이루어진다.
        int[] xes = lottos[0][0]; (x) 계층이 달라요.
        int[] xes = lottos[0];    참조 변수는 새로운 이름을 만드는 것이다.
        int[] xes = lottos; (x)   계층이 달라요.
        int[][] xes = lottos;     (o) 쌉가능!

        */
        //이렇게 대입하면 처음에 선언한 배열 크기에 맞게 늘어간다.
        //다른 배열을 만들때는 new를 사용해서 해야한다.
        lottos[1]=new int []{9,9,9,9,9,9,9,9,9,9};

        for(int i=0;i<3;i++) {
            for (int j = 0; j < 6; j++)
                System.out.printf("%4d, ",lottos[i][j]);

            System.out.println();
        }

    }
}

'IT > JAVA' 카테고리의 다른 글

[Java] 함수 오버로드(overload)  (1) 2023.07.04
[Java]구조적인 프로그래밍(메서드)  (2) 2023.06.28
[Java] 배열(Array)  (0) 2023.06.21
[Java]비트 연산자로 데이터값 추출하기  (0) 2023.06.12
[Java] 문자열 (String)  (2) 2023.06.10

🟩 배열이란? 

  • 같은 타입의 여러 변수를 하나의 묶음으로 다루는 것
  • 많은 양의 데이터를 저장하기 위해 사용함
  • 쉽게 말해서 임시저장소이다.
  • 값 로드하기, 값 위치 찾기, 배열이동, 값 바꾸기, 값 이동하기... 등등 여러 가지 방법으로 사용된다.
  • 배열은 기본형 변수를 사용해도 참조형 객체라고 한다.
  • 인덱스(index)의 범위0부터 '배열길이-1'까지!

 

byte[] a=new int[];
short[] b=new short[];
int[] c=new int[];
long[] d=new long[];
boolean[] e=new boolean[];
float[] f=new float[];
double[] g=new double[];
char[] h=new char[];

 기본형 타입의 배열 선언 방법

 

int[] numbers;// int 형 변수의 numbers라는 배열 선언.
numbers = new int[10];// numbers에 크기 10인 배열 할당.
numbers[1] = 3; // numbers의 2번째에 숫자 3을 할당.
int[ ] kors = {1, 2, 3}

 

위에 방식처럼 다르게 배열을 선언할 수 있다.


✅ 간단 퀴즈 #1
   파일에서 값 90을 찾아서 그 값을 1번째 위치 값과 바꾸어 저장하시오.
   
   100 23 46 82 57 90 50 46 80 20 50 70

 

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.charset.Charset;
import java.util.Scanner;

public class array {
	public static void main(String[] args) throws IOException {
		int[] nums = new int[100];// 숫자 저장 공간

		int size=0;//데이터 Size측정
		
		// 값 로드하기
		{
			FileInputStream fis = new FileInputStream("JavaPrj/res/Data/data.txt");
			Scanner sc = new Scanner(fis);
			
			for (int i = 0; sc.hasNext(); i++) {
				nums[i] = sc.nextInt();
				size++;
			}
			sc.close();
			fis.close();
		}

		//nums 출력하기
		//100, 23, ...70
		{
			for(int i=0;i<size;i++)
				System.out.printf("%3d ",nums[i]);
		}
		System.out.println();

		int index = -1;// index가 0부터 시작하면 배열에서 0값으로 인식할 수 있어서 범위 밖에있는 값 지정.
		// 위치 찾기
		{
			for (int i = 0; i < size; i++)
				if (nums[i] == 90) {
					index = i;
					break;//효율을 위해서!
				}
		}

		// 값 바꾸기
		{
			int temp; //temp라는 변수는 이 구역에서만 사용해서 여기에 변수를 선언했음
			temp = nums[index]; //temp에 nums[5](90)을 저장함.
			nums[index] = nums[0]; //nums[5]에 nums[0](100)을 저장함.
			nums[0]=temp; // nums[0]에 90을 저장함. 
		}

		// 값 저장하기
		{
			FileOutputStream fos = new FileOutputStream("JavaPrj/res/Data/data.txt");
			PrintWriter fout = new PrintWriter(fos, true, Charset.forName("UTF-8"));
			
			//파일 출력
			for(int i=0;i<size;i++)
				fout.printf("%d ",nums[i]);
			
			//콘솔 출력 
			for(int i=0;i<size;i++)
				System.out.printf("%3d ",nums[i]);
			
			fout.close();
			fos.close();
		}

		
	}
}

 

주제와 조금 벗어난 이야기지만 여기서 "//값 바꾸기"에 대해서 조금 더 자세히 알아보자.

 

// 값 바꾸기
		{
			int temp; //temp라는 변수는 이 구역에서만 사용해서 여기에 변수를 선언했음
			temp = nums[index]; //temp에 nums[5](90)을 저장함.
			nums[index] = nums[0]; //nums[5]에 nums[0](100)을 저장함.
			nums[0]=temp; // nums[0]에 90을 저장함. 
		}

사람한테 "100 23 46 82 57 90" 이런 숫자를 주고, 두 숫자의 자리를 바꾸라고 하면 지우개로 지우고 다시 쓰면 될 거다.

 

반면 컴퓨터는 사람처럼 지우개로 지우고 다시 쓸 수 없다. 그래서 "temp"라는 임시 저장소를 만들어서 "저글링"하듯 값을 돌려주면 된다.

 

이 그림을 보면 이해하기 쉬울것이다.

 

  1. temp라는 변수를 새로 선언한다.
  2. tempnums[5](90)을 저장해준다. num[5]temp에 값을 넘겨주고 num[5]를 temp처럼 사용할 수 있다.
  3. nums[5]nums[0](100)을 저장한다.
  4. nums[0]90을 저장한다.

 


 

https://beastit.tistory.com/36

 

[Byte Order]Big Endian(빅 엔디안) & Little Endian(리틀 엔디안)

🟩 Byte Order (바이트 저장 순서) 컴퓨터는 데이터를 메모리에 저장할 때 바이트(byte) 단위로 나눠서 저장합니다. 하지만 컴퓨터가 저장하는 데이터는 32비트(4바이트) 또는 64비트(8바이트)로 구성

beastit.tistory.com

 

글 시작 전에 위에 글을 먼저 보면 왜? 하는지 알 수 있다.

 

✅ 비트맵 이미지로 필요한 데이터 추출하기

 

맨 위부터 보면 Signature(2byte), File Size (4byte)...... 각 층마다 4byt의 해당 정보들을 가지고 있다.

 

우리가 필요한 정보는 Image Width, Height의 데이터를 추출하고 싶다.

 

19~22바이트, 23~26바이트에 접근하면 추출 할 수 있음

 

" 1314x736 "

 

 

 

 

import java.io.FileInputStream;
import java.io.IOException;

public class homework {

	public static void main(String[] args) throws IOException {
		// 4바이트 데이터 읽기
		int n1 , n2, n3, n4 ;
		int n5 , n6, n7 , n8 ;

		// Image Width & Height
		{
			FileInputStream fis = new FileInputStream("res/pic1.bmp");

			//필요없는 데이터 건너뛰
			//Signature
			fis.read();
			fis.read();

			//File Size
			fis.read();
			fis.read();
			fis.read();
			fis.read();

			//Reserved 1,2
			fis.read();
			fis.read();
			fis.read();
			fis.read();

			//File Offset to PixelArray
			fis.read();
			fis.read();
			fis.read();
			fis.read();
			
			//DIB Header Size
			fis.read();
			fis.read();
			fis.read();
			fis.read();
			
			//Image Width
			n1=fis.read();
			n2=fis.read();
			n3=fis.read();
			n4=fis.read();
			
			//Image Height
			n5=fis.read();
			n6=fis.read();
			n7=fis.read();
			n8=fis.read();
			
			
			
			int width = n1 << 0 | n2 << 8 | n3 << 16 | n4 << 24;
			int height = n5 << 0 | n6 << 8 | n7 << 16 | n8 << 24;
			
			System.out.printf("Width : %d, Height : %d\n",width,height );

		}

	}

}

 

✅ 결과

 


 

비트맵 파일을 바이너리 에디터로 보면 Image Width (19~22바이트), Image Height (23~26바이트)

 

🔸 Image Width : 034 005 000 000

🔸 Image Height : 224 002 000 000

 

인텔 CPU 계열에서는 낮은 주소에 데이터의 낮은 바이트부터 저장하는 방식"리틀 엔디안(Little Endian)" 방식으로 저장한다.

우리는 이것을 낮은 주소에 데이터의 높은 바이트부터 저장하는 방식"빅 엔디안(Big Endian)" 방식으로 비트연산자를 써서 저장할 것이다. 

 

int width = n1 << 0 | n2 << 8 | n3 << 16 | n4 << 24;
int height = n5 << 0 | n6 << 8 | n7 << 16 | n8 << 24;

 

  • n1 :                                                                 0010 0010 (34)
  • n2 :                                            0000 0101 0000 0000 (5)
  • n3 :                      0000 0000 0000 0000 0000 0000 (0)
  • n4 : 0000 0000 0000 0000 0000 0000 0000 0000 (0)  

  width : 0000 0000 0000 0000 0000 0101 0010 0010  

 

or( | ) 연산자를 사용하면 위와 같이 비트 이동이 이루어 지면서 저장 값이 바뀌게 된다.

 

  • n5 :                                                                  1110 0000 (224)
  • n6 :                                            0000 0010 0000 0000 (5)
  • n7 :                       0000 0000 0000 0000 0000 0000 (0)
  • n8 :  0000 0000 0000 0000 0000 0000 0000 0000 (0)  

  width : 0000 0000 0000 0000 0000 0010  1110  0000 

public class program {

	public static void main(String[] args) {

		String name1 = "아이유";// 실행환경이 입힌 갑옷
//		String name2 = "아이유";
		String name2 = new String("아이유");// 내가 입힌 갑옷
		// ==이라는 기호가 값이 같은지? 박스가 같은지? 비교해보자.
		// 결과는 false가 나온다. 참조하는 객체가 달라서 이럼.

		System.out.println(name1 == name2);// 같은 객체를 참조하고 있는지를 비교 false
		System.out.println(name1.equals(name2));// 객체의 값이 같은지를 비교 true
		System.out.println(name1 == "아이유");// 결과는 true name1박스에서 만든 박스로 비교하는것. true

		System.out.println("----------------------------------------------");

		// 파일명에서 확장자를 제외한 파일명만 출력하시오.
		// =위의 팡리명에서 점(.)이 있는 곳까지의 문자열을 출력하시오.(단 점(.) 제외)
		String fileName = "photo.jpg";
		System.out.println(fileName.length());// 문자열의 길이를 알 수 있다. 결과 값 : 9
		System.out.println(fileName.indexOf("."));// "." 의 위치를 알 수 있다. 5번째에 위치하고 있음.
		System.out.println(fileName.substring(0, 3));// 0~3까지의 문자만 출력한다. pho가 나온다.
		System.out.println(fileName.substring(0, 5));// 0~5까지의 문자만 출력한다. photo가 나온다.

		String p = fileName.substring(0, 5);
		String w = fileName.substring(6, 9);
		System.out.printf("\n%s"+"%s\n",p,w);
		
		
		int index = fileName.indexOf(".");// 점(.)이 위치한값을 구해서 index에 저장한다.
		String name = fileName.substring(0,index);//
		System.out.println(name);//끝나는 부분을 index으로 설정.
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		

		int x = 3;
		Integer 정수갑옷 = Integer.valueOf(x);// new Integer(x); Boxing
		int x1 = 정수갑옷.intValue();// Unboxing
		

		String y = "hello";// 태생이 갑옷을 입고있는 문자열!

		double d1 = 3.9;
		Double 더블갑옷 = Double.valueOf(d1);// new Double(d1);
		double d2 = 더블갑옷.doubleValue();// Unboxing

		// ---정수를 문자열로 변환 & 문자열을 더블로 변환.
		int n1 = 10;
		String s1 = String.valueOf(n1);

		String s2 = "30.2";
		double n2 = Double.parseDouble(s2);
	}

부동소수점,고정소수점

 

  • 고정소수점(Fixed Point)

소수점의 위치를 고정시켜 표현

비트를 절반으로 나누어 정수와 소수를 표현하는 방식

구현하기 편하고 연산속도가 빠름

표현 가능한 수가 적고 제한된 부분에서만 사용 가능(소수점 아래 긴 경우 사용 불가)


  • 부동소수점(Float Point)

정수와 소수를 구분하지 않고 두 수를 하나의 공간으로 합쳐서 표현하는 방법

소수점을 고정시키지 않은 표현 방식으로 유연하고 정밀하게 표현 가능


<실수 12.5를 부동소수점으로 표현하는 방법>

실수 12.5 -> 2진수 1100.1 -> 1.1001e3

 

0.5 =  0.1

0.25 =  0.01

0.125 =  0.001




개체(Entity)vs 객체(Object)vs 인스턴스(Instance)vs 클래스(Class)

 

  • 개체(entity): 사고하는 개념적 정의 혹은 단위. 아직 메모리에 할당되지 않은 코드

          ex) type, 메뉴판, 제품카탈로그


  • 객체(Object): 주문한 메뉴가 실체화 된 것.

       실체화하기 위해선 new를 이용하여 메모리에 올린다.

 

       FileOutputStream fout = new FileOutputStream("res/data.txt");

 

       개체 참조변수 객체


  • 인스턴스(Instance): 객체를 실체화 시킨 것. 클래스를 통해 구현한 객체

  • 클래스(Class): 객체를 실체화 하기 위해 만든 설계도

 

'IT > JAVA' 카테고리의 다른 글

[Java] 문자열 (String)  (2) 2023.06.10
[Java] 부동소수점, 고정소수점  (0) 2023.06.08
[Java] 입출력 스트림  (0) 2023.06.08
[Java] Reference Type(참조형식)=참조 변수  (0) 2023.06.08
[Java] 변수(Variable)  (0) 2023.06.08

+ Recent posts