Java - 변수

kojam9041·2022년 3월 15일
0

KH정보교육원 - JAVA

목록 보기
4/12

변수

* 메모리에 하나의 값을 저장할 수 있는, 방과 같은 기억 공간(메모리공간)이다.
* 변수 공간에 기록된 값은 고정되어 있지 않고, 다른 값이 기록되면 자동으로 덮어씌워질 수 있다.
* 기록 저장되는 값의 종류에 따라, 변수 공간의 자료형이 결정된다.

데이터 저장 단위

* 저장공간이 제한적이기때문에, 크기에 대한 기준과 cpu가 데이터를 처리할 때의 기준이 필요하다.
	- 비트(bit) : 데이터 저장의 최소단위. 2진수(0,1)의 값 하나를 저장할 수 있는 메모리 공간을 의미한다.
	- 바이트(byte) : 데이터 처리 또는 문자의 최소 단위. 1byte = 8bit이다.
* 1byte의 경우, -128 ~ 127까지 표현할 수 있다.(256자, 2의0승 ~ 2의7승)
* 양수로, 01111111로 127까지 표현할 수 있다.
* 맨 앞자리의 0이 1이 되는 순간, 음수가 되며 11111111로 -127까지 표현할 수 있다.
* 맨 앞자리의 0,1을 부호비트라고 한다.
* 여기서, 10000000이 되면 0에 부호비트를 적용하는 것이라 -128이라고 한다.

데이터 오버플로우

* 만약, byte형인데 지정된 값의 범위를 넘으면 어떻게 되는가?
* 예를들어, 127까지의 byte에 +1을 하면 어떻게 되는가?
* 127의 경우, 01111111이고, 여기에 +1을 하면 10000000이 되기때문에, -128이 된다.

자료형

1.기본자료형

* Java는 값을 8개의 기본형으로 구분한다.
* Java컴파일러에 의해서 해석되는 자료형을 의미한다.
자료형키워드크기기본값값의 범위
논리형boolean1bytefalsetrue 또는 false
문자형char2byte'\u0000'0 ~ 65,536
정수형byte1byte0-128 ~ 128
short2byte0-32,768 ~ 32768
int4byte0-2의 31승 ~ 2의 31승-1
long8byte0L-2의 63승 ~ 2의 63승-1
실수형float4byte0.0f-3.4E38 ~ +3.4E38
double8byte0.0 또는 0.0d-1.7E308 ~ +1.7E308

2.참조자료형

* 클래스를 사용자 정의 자료형이라고 하며, 클래스를 자료형으로 하여 선언된 변수를 레퍼런스변수라고 한다.
* 자유메모리 영역인 Heap메모리에 생성된 객체의 주소를 저장한다.
* Java에서는 메모리 주소를 직접 소스코드로 참조하는 것은 불가능하다.

변수의 선언 및 초기화

* [표현법]
* 자료형 변수명;
----------------------------------------------------------------------------------
TestVariable.java
public class TestVariable{
    public static void main(String[] args){
        boolean flag;
        char grade;
        byte value;
        short svalue;
        int num;
        long price;
        float tax;
        double score;
    } 
}
----------------------------------------------------------------------------------

변수 초기화

* 변수 선언과 동시에 초기값 대입을 처리하는 것을 말한다.
* [표현법]
* 자료형 변수명 = 초기값;
----------------------------------------------------------------------------------
TestVariableInit.java
public class TestVariableInit{
    public static void main(String[] args){
        boolean flag = false;
        char grade = 'A';
        byte value = 90;
        short svalue = 2500;
        int num = 1250000;
        long price = 2350L;
        float tax = 3.3f;
        double score = 99.5;
          
        System.out.println("flag : " + flag);
        System.out.println("grade : "+ grade);
        System.out.println("value : "+value);
        System.out.println("svalue : "+svalue);
        System.out.println("num : "+num);
        System.out.println("price : "+price);
        System.out.println("tax : "+tax);
        System.out.println("score : "+score);
    } 
}
----------------------------------------------------------------------------------

문자열 초기화

* 다른자료형 + "문자열" = "문자열"
* "문자열" + 다른자료형 = "문자열"
* "문자열" + "문자열" = "문자열"
* 이처럼, 문자열과 연산을 한 결과는 문자열로 나타낸다.
----------------------------------------------------------------------------------
String str = "기차";
String str = new String("기차") //나중에 함.
String str = "기차" + "칙칙폭폭";
String str = "기차" + 123 + 45 + "출발";
----------------------------------------------------------------------------------

상수

* 수학에서는 변하지 않는 수를 의미한다. 자바에서도 마찬가지이다.
* 컴퓨터상에서 한번만 저장(기록)할 수 있는 메모리 공간을 생성하는 것을 의미한다.
* 주의할 점
* 1. final이라는 키워드를 붙여서 선언한다.
* 2. 상수명은 항상 대문자로 작성한다.
----------------------------------------------------------------------------------
// 상수 선언 방법
final int AGE;

// 상수 초기화 방법
final int NUM;
NUM = 100;
=> final int NUM = 100;
----------------------------------------------------------------------------------
*******************************************************************************
[오류메세지]
The final local variable AGE cannot be assigned. 
It must be blank and not using a compound assignment
=>final키워드가 붙은 지역변수인 AGE는 대입 당할 수 없다.
=>상수에 이미 값이 있을 경우 대입자체가 되지 않는다.
*******************************************************************************

변수 활용

----------------------------------------------------------------------------------
TestUsingVariable.java
public class TestUsingVariable{
  public static void main(String[] args){
      int price = 2500, quantity = 3;
      int totalPrice = price * quantity;
      
      System.out.println("가격 : " + price + " 원, 수량 : "+quantity+ "개");
      System.out.println("총 구매가격 : " + totalPrice + "원" );
  }
}
----------------------------------------------------------------------------------

변수명 작성 규칙

1. 대소문자가 구별되며, 길이에 제한이 없다.
2. 예약어를 사용할 수 없다.
3. 숫자로 시작하면 안된다.
4. 특수문자는 '$'와 '_'만 허용된다.

이외 작성 규칙

1. 클래스 이름은 반드시 대문자로 시작한다.
2. 메소드, 변수 이름은 소문자로 시작하며, 
여러 단어를 합쳐서 의미가 부여된 이름을 작성한다.
3. 상수의 이름은 모두 대문자로 작성한다.
4. 여러 개의 단어이가 이어진 경우, 낙타봉 표기법을 사용한다
(두번째 단어 이후 첫글자 대문자)
5. 상수가 여러개의 단어로 구성될 경우, 단어간 구분에 '_'을 이용한다

예약어

* 해당 프로그램 언어에서 필요에 의해 기능이 이미 정의되어 있는 단어들이다.
* Java예약어는 모두 소문자로 대략 50여개가 있다.
* 예약어는 변수명, 클래스명, 메소드명으로 사용할 수 없다.
abstractassertbooleanbreakbyte
casecatchcharclassconst
continuedefaultdodoubleelse
enumextendsfalsefinalfinally
floatforgotoifimplements
importinstanceofintinterfacelong
nativenewnullpackageprivate
protectedpublicreturnshortstatic
strictfpsuperswitchsynchronizedthis
tryvoidwhile

형변환

* 값의 자료형을 바꾸는 개념이다.
*
* 컴퓨터상에서 값 처리 규칙
1. 대입연산자를 기준으로, 왼쪽과 오른쪽은 같은 자료형이어야 한다.
2. 같은 자료형끼리만 연산이 가능하다
3. 연산 결과도 같은 자료형으로 산출된다.
*
* 형변환의 종류
1. 자동형변환(작은->큰) : 자동으로 형변환되어, 코드상으로 직접 형변환할 필요가 없다
2. 강제형변환(큰->작은) : 직접 형변환을 한다(명시적 형변환, 형변환연산자)

자동형변환

----------------------------------------------------------------------------------
// 자동 형변환 : 작은 byte의 값을 큰 byte의 Variable에 담을 경우 발생한다.
public void autoCasting() {

		// 자동 형변환이 되는 case
		
		/* 1. 정수형 int(4byte) -> 실수형 double(8byte) */
		int i1 = 10;
		double d1 = /*(double)*/i1;
		System.out.println("d1 : " + d1); // 10.0
        
		int i2 = 12;
		double d2 = 3.3;
		double result2 = /*(double)*/i2 + d2;
		System.out.println("result2 : "+result2); // 15.3
		
		/* 2. 정수형 int(4byte) -> 정수형 long(8byte) */
		int i3 = 1000;
		long l3 = /*(long)*/i3;
		long l4 = 2000; 
		// L을 붙이지 않아도 long으로 자동 형변환이 된 것이다.
		// 본래는 그냥 숫자만 쓰면 int형을 의미한다.
		System.out.println("l3 : "+l3); 
		System.out.println("l4 : "+l4);
		
		/* 3.[특이케이스] 정수형 long(8byte) -> 실수형 float(4byte) */
		// 정수가 실수로 변환될 경우, 큰 size의 정수가 작은 size의 실수로 변환 가능하다.
		// 이는 4byte float형이 사실 8byte long형보다 담을 수 있는 값의 범위가 크기 때문이다.
		long l5 = 1000000000;
		float f5 = /*(float)*/l5;
		System.out.println("f5 : "+f5) // 1.0E9
		
		/* 4.[특이케이스] 문자형 char(2byte) <---> 정수형 int(4byte) 
		   : 양방향 형변환 가능*/                                                
		char ch = /*(char)*/65;
		System.out.println("ch : " +ch);  // 'A'
		
		int num = /*(int)*/'A';
		System.out.println("num : "+num); // 65
		
		System.out.println((int)'김'); // 44608
		/*
		 * [참고] 아스키 코드 표
		 * 각 문자별로 고유한 숫자값으로 대치되서 표현되는 개념
		 * (0~127 : 대소영문자, 숫자, 특수문자)
		 * 'A' = 65 , 'a' = 97
		 * '김' = 44608
		 * [참고] 유니코드 표
		 * 각 문자별로 고유한 숫자값으로 대치되서 표현되는 개념
		 * 아스키 코드의 확장된 개념이라고 보면 된다.
		 * (0~65536 : 영어, 숫자, 특수문자, 그 이외의 언어문자)
		 */
		int sum = 'A' + 10;
		System.out.println("sum : " + sum); // 75
		System.out.println("sum : " + (char)sum); // k
	
		
		/* 5.[특이케이스] byte끼리, short끼리의 연산 */
		byte b1 = 1;
		byte b2 = 10;
		short s1 = 1;
		short s2 = 10;
		// byte result = b1 + b2;
		// [오류메세지]
		// Type mismatch: cannot convert from int to byte
		// byte나 short로 연산시, 결과값이 int(4byte)로 취급한다.
		byte result1 = (byte)(b1 + b2);
		short result11 = (short)(s1 + s2);
		System.out.println("result1 : "+result1);
		System.out.println("result11 : "+result11);
		// 이렇게 b1+b2로 연산한 결과인 int형을 byte형으로 바꾸어 준다
		// (byte)b1 + (byte)b2로 하더라도 연산 결과가 11로 int형이기 때문에
		// 결과값 전체를 byte로 하지 않는 이상은 오류가 뜬다.
		// short도 마찬가지이다.
	}
----------------------------------------------------------------------------------

강제형변환

----------------------------------------------------------------------------------
	// 강제(명시적) 형변환 : 큰 크기의 자료형을 작은 크기의 자료형으로 형변환 할 경우(형변환 연산자 사용)
	public void forceCasting() {
		// 강제 형변환을 해야하는 case
		
        /*1. double(8byte) -> float(4byte)*/
		float f1 = 4.0;
		// [오류메세지]
		// Type mismatch: cannot convert from double to float
		// 값 뒤에 f를 붙여주거나 값 앞에(float)을 붙여줘야 한다.
		double d2 = 8.0;
		float f2 = (float)d2;
		
		/*2. double(8byte) -> int(4byte)*/
		double d3 = 10.89;
		int i3 = (int)d3; 
		System.out.println("i3 : "+ i3); // 10
		// [주의사항]
		// 데이터의 손실이 일어날 수 있다.(강제 형변환은 신중히!)
		// => 소수점 아래 내용이 절삭되었다.
		
		int iNum = 10;
		double dNum = 5.89;
		int iSum = iNum + dNum;
        // [오류메세지]
		// iNum이 상대적으로 큰 size인 double형으로 자동변환이 되고
		// dNum과 덧셈연산이 행해진 상태이다.
		// 즉, 15.89라는 double형인 상태로, int iSum의 값이 된 상태이다.
		// [해결방법]
		// 1. 연산 결과를 통으로 강제 형변환을 해준다.
		int iSum1 = (int)(iNum + dNum);
		System.out.println("iSum1 : "+iSum1); // 15라는 값이 나온다.
		// 2. 각각의 값을 결과의 자료형에 맞게 강제 형변환을 해준다.
		int iSum2 = iNum + (int)dNum;
		System.out.println("iSum2 : "+iSum2); // 15라는 값이 나온다.
		// 3. 결과의 자료형을 연산 결과에 맞게 강제 형변환을 해준다.
		double iSum3 = iNum + dNum;
		System.out.println("iSum3 : "+iSum3); // 15.89라는 값이 나온다.
		
		/*
		 * 강제 형변환을 주로 하는 경우
		 * 오류 발생시 : Type mismatch : cannot convert from ~ to ~...
		 */
	}
----------------------------------------------------------------------------------

스캐너 클래스

* Java에서 이미 제공하고 있는 패키지(java.util.Scanner)
* Scanner클래스 안에 작성되어 있는 메소드를 호출하여 사용한다.
* sc.Method명();
* [참고] 출력시에는 System.out.printXXX()를 사용했었다.
-------------------------------------------------------------------------------
package com.kh.variable;

import java.util.Scanner;

//사용자가 Keyboard로 입력한 값을 Variable에 기록하는 방법
public class B_KeyboardInput {

	public void inputTest1() {
		// 1. 다른 Package, Class내의 Method를 호출할 경우에는 대변할 이름을 먼저 생성(new)
        Scanner sc = new Scanner(System.in);
		// 2. import문 작성 
		// System.in : 키보드로 입력받은 값을 byte단위로 받아들이겠다는 의미이다.
        
        /*
		 * Scanner Class 내의 입력받는 Method의 종류들
		 * 1. next() 		: 문자열을 입력받을 때 사용. 공백 전까지 
		 * 2. nextLine() 	: 문자열을 입력받을 때 사용. 엔터를 치기 전까지(공백포함)
		 * 3. nextInt() 	: Int타입의 정수를 입력받을 때 사용.
		 * 4. nextByte() 	: Byte타입의 정수를 입력받을 때 사용.
		 * 5. nextShort() 	: Short타입의 정수를 입력받을 때 사용.
		 * 6. nextLong() 	: Long타입의 정수를 입력받을 때 사용.
		 * 7. nextDouble() 	: Double타입의 실수를 입력받을 때 사용.
		 * 8. nextFloat() 	: float타입의 실수를 입력받을 때 사용.
         * => next계열의 모든 Method들은 엔터키를 누를때까지 대기한다.
		 */
        
        
		// 사용자의 인적사항(이름, 나이, 키)을 입력받는 프로그램
		// 1. 입력받고자 하는 내용을 먼저 출력해서 사용자로부터 입력을 유도한다.
		System.out.print("당신의 이름은 무엇입니까?");
		// 2. 사용자의 이름을 입력받아서 Variable에 담는다.
		String name = sc.nextLine(); 
		
		// 나이 입력받기
		System.out.print("당신의 나이는 몇살입니까?");
		int age = sc.nextInt();
		sc.nextLine(); // 버퍼에 남아있는 엔터값을 비워주기 위해 실행한다.
		// [주의사항] 
		// nextInt()를 호출 후 반드시 nextLine()를 한번 실행해야 한다.
		// => 버퍼(임시저장소)공간에 남아있는 엔터값을 사용자가 자동으로 입력했다고 간주한다.
		// => 이후, 곧바로 메모리에 저장되어 Variable에 담긴다.
        
		// 키 입력받기
		System.out.print("당신의 키는 얼마입니까?");
		double height = sc.nextDouble(); 
		sc.nextLine(); // 버퍼에 남아있는 엔터값을 비워주기 위해 실행한다.
		// nextDouble()도 마찬가지로 nextLine()을 한번 실행해야 한다.
        
		System.out.print("키 "+ height +"cm, " + "나이 " + age + "세, "
		+ name + "님 환영합니다.");
		

	}
	public void inputTest2() {
		
		Scanner sc = new Scanner(System.in);
        
		// 사용자로부터 인적사항(이름, 나이, 성별, 키)을 키보드로 입력 받아 출력하는 프로그램
		// 성별 입력 유도 : 남자(Male), 여자(Female)
		System.out.print("이름 : ");
		String name = sc.nextLine();
		System.out.print("나이 : ");
		int age = sc.nextInt();
		sc.nextLine();
        
		/*
		 * 문자열로 입력받고나서 첫번째 문자 하나만을 뽑아낸다.
		 * "apple" 문자열 => 인덱스(Index) : 컴퓨터는 숫자를 0부터 센다.
		 * 1번째 : a => 컴퓨터 : 0번째
		 * 2번째 : p => 컴퓨터 : 1번째
		 * 3번째 : p => 컴퓨터 : 2번째
		 * 4번째 : l => 컴퓨터 : 3번째
		 * 5번째 : e => 컴퓨터 : 4번째
		  
		 * 문자열로부터 해당위치(Index)의 문자 하나만을 뽑아내주는 Method
		 * => 해당문자열.charAt(Index)이라는 Method임.
		 * 1. 키보드로 입력받는다 =>nextLine()
		 * 2. 입력받은 문자열로부터 charAt()을  실행
		 * => sc.nextLine().charAt(0);
		  
		 * [주의사항]
		 * 만약 내가 뽑고자 하는 위치값이 문자열의 크기보다 크다면?
		 * abc.charAt(100);
		 * [오류메세지]
		 * char gender = sc.nextLine().charAt(100);
		 * Exception in thread "main" java.lang
		 * .StringIndexOutOfBoundsException 
		 * : String index out of range: 100
		 * =>문자열의 Index가 범위를 벗어났다.
		 * Male은 총 4글자(0,1,2,3)인데 100번째 인덱스의 글자를 추출하고자 해서 발생하였다.
		 */
		System.out.print("성별(M/F) : ");
		char gender = sc.nextLine().charAt(0);
		
		System.out.print("키 : ");
		double height = sc.nextDouble();
		sc.nextLine();
		
		// 출력해보기
		System.out.println(name + "님의 개인정보");
		System.out.println("성별 : "+gender);
		System.out.println("나이 : "+age);
		System.out.println("키 : "+height);
	}
    
	// [참고]
	// 만약,nextInt 다음에 nextLine으로 버퍼를 지워주지 않은 경우. 
	public void inputTest3() {
		//사용자로부터 인적사항을 입력받는 것(이름, 나이, 주소)
		Scanner sc = new Scanner(System.in);
		System.out.print("이름 : ");
		String name = sc.nextLine();
		
		System.out.print("나이 : ");
		int age = sc.nextInt();
		sc.nextLine(); //=> 버퍼(임시보관소)를 비워주기 위해 사용한다.
		//nextInt를 이용하여 숫자값을 받고나서 , 그 이후에 nextLine을 사용하면 발생한다.
		//nextLine대신 next를 사용하면 공백에 입력할 수 있는 구간이 생겨난다.
		
		System.out.print("주소 : ");
		String addr = sc.nextLine();
		
		System.out.print(addr + "에 사는 " + age + "살 " + name + "님 환영합니다.");
	}
}
----------------------------------------------------------------------------------

프린트 클래스

----------------------------------------------------------------------------------
package com.kh.variable;

public class D_Printf {
	
	/*
	 * System.out.println(출력하고자 하는 값); 
	 * => 값을 출력한 후에 줄바꿈(커서가 다음줄에 찍힘.)을 한번 해준다.
	 * System.out.print(출력하고자 하는 값);
	 * => 값을 출력한 후에 줄바꿈(커서가 해당줄에 찍힘.)을 하지 않는다.
	 * 
	 * System.out.printf()에 대하여 배워본다
	 * [표현법]
	 * System.out.printf("출력하고자 하는 형식", 출력하고자 하는 값);
	 * => f는 format(형식)을 의미한다.
	 * => 형식에 맞춰서 값들이 출력되나, 줄바꿈은 일어나지 않는다.
	 * => 개행은 \n을 이용한다.
	 * => "출력하고자 하는 형식"에 구멍을 뚫고, 출력하고자 하는 값으로 구멍을 메꾼다고 생각하면 된다.
	 * 형식
	 * %d : 정수(decimal, 10진수)가 들어갈 자리
	 * %f : 실수(float)가 들어갈 자리
	 * %c : 문자(character)가 들어갈 자리
	 * %s : 문자열(String)이 들어갈 자리
	 */
	public void printfTest(){
		
		//정수 테스트(%d)
		int iNum1 = 10;
		int iNum2 = 20;
		
		// iNum1 : xx, iNum2 : xx => 이런 형식으로 출력한다.
		// println 사용
		System.out.println("iNum1 : "+iNum1+", iNum2 : "+iNum2);
		// printf 사용
		System.out.printf("iNum1 : %d, iNum2 : %d",iNum1,iNum2);
		
		// 정수테스트(%d)
		System.out.println("\n"+iNum1 + " + " +iNum2 + " = " + iNum1+iNum2);
		System.out.println(iNum1 + " + " +iNum2 + " = " + (iNum1+iNum2));
		// 괄호를 사용하지 않으면 연산작용이 아닌 문자열로 취급한다.
		
		System.out.printf("%d + %d = %d \n",iNum1,iNum2,(iNum1+iNum2));
		// 줄바꿈이 되지 않아 개행도 추가해준다.
		
		// 함께 사용할 수 있는 옵션
		System.out.printf("%5d \n",iNum1); // 5칸의 공간 중 오른쪽 정렬을 함.
		System.out.printf("%-5d \n" ,iNum2); // 5칸의 공간 중 왼쪽 정렬을 함.
		
		// 실수테스트(%f)
		double dNum = 4.27546789;
		System.out.printf("dNum : %f \n",dNum); 
		// 4.275468이라는 값이 나온다.
		// %f : 소수점 아래 7번째 줄에서 반올림이 되어 소수점 아래 6번째까지만 출력된다.
		System.out.printf("dNum : %.1f \n",dNum);
		// 4.3이라는 값이 나온다.
		// 소수점 아래 2번째 줄에서 반올림이 되어 소수점 아래 1번째까지만 출력된다.
		
		// 문자 및 문자열 테스트(%c, %s)
		char ch = 'a';
		String str = "Hello";
		System.out.printf("%c %s \n",ch,str);
		// a Hello라는 값이 나온다.
		System.out.printf("%c    %s \n",ch,str);
		System.out.printf("%c \t %s \n",ch,str);
		// \t : Tab키를 한번 누른 효과를 준다.
		// \n : Enter키를 한번 누른 효과를 준다.
		
		// 옵션
		System.out.printf("%C %S",ch, str);
		// 알파벳 소문자일 경우, 대문자로 바꾸어서 출력한다.
		
		/*
		 * printf : 포맷 한 번을 제시하여 간편하게 출력할 수 있게 해준다.
		 * 	                  단, 지정한 Format의 종류와 개수 and Variable의 종류와 개수가 맞아야 한다.
		 */
	}
}
----------------------------------------------------------------------------------

0개의 댓글