Java

변수

늦은산책 2023. 4. 24. 11:46

변수

  • 정보들을 저장할 수 있는 메모리 공간(RAM)
  • 메모리 공간
    • 하나의 메모리 공간을 1byte 단위로 나눈것이다.
  • 메모리 주소
    • 하나의 큰 메모리 공간안에 있 각각 저장공간을 뜻하는데 그 저장공간은 0부터 연속적인 숫자로 번호를 매긴다
    • 하나의 메모리 주소에는 하나의 정보만이 저장되고 새로운 값을 저장하면 기존에 있던 정보는 지워진

메모리 주소 안에 저장되어 있는 정보를 사용하는데 문제는 우리가 그 정보를 사용하고 싶을때마다 메모리 주소의 번호를 기억해 내야한다 하지만 그 수를 일일히 기억해내는것은 굉장히 어려운 일이였고 사람이 기억하기 쉬운 방법을 만들었다 

 

그 방법은 숫자로 이루어진 메모리 주소에 별칭을 붙여서 우리가 기억하기 쉽게 만들어내는것이다. 

그 별칭을 변수라고 한다 

 

변수의 선언

  • 변수의 선언 이유
    • 값을 저장할 공간을 할당하고 그 할당된 곳에 있는 정보를 내가 사용하고 싶을때 훨씬 쉽게 하기 위해서 이다
  • 변수 선언의 방법
    • 변수타입 변수이름; 
    • 예를 들어 정수 타입의 나이라는 이름의 변수를 저장하고 싶다면 int age; 로 작성하면 된다.

 

변수에 값 저장하기

  • 변수에 값 저장하기
    • 앞서 우리는 int age; 라는 변수를 지정했고 이 안은 정수(int)값을 저장하기로 했다 
    • age = 25; 이것이 정수형의 정보를 age라는 변수명을 가진 메모리 저장장소에 저장된것이다.
    • 여기서 조금 오해가 있을수 있다. 우리의 평소 수학에 따르면 "=" 의 표시는 "~와 같다" 라는 뜻일텐데 프로그래밍의 "="뜻은 대입한다 라고 봐도 무방하다
    • 즉, 오른쪽에 있는 값을 왼쪽에 저장하겠다 라고 읽는것이다
    • int age = 25 ; 라고 지금까지의 과정을 한 줄로 작성을 마칠수 있다
  • 변수의 초기화
    • 우리가 지금까지 한 행동 ( 변수에 값을 처음으로 저장하는것 ) 을 변수의 초기화라고 한다
    • 그래서 보통 변수를 선언하는 동시에 초기화를 하는것이 좋다
    • int age = 0 ; 이런식으로 말이다.
  • 번외
    • 그렇다면 만약 내가 2개 이상의 int 형인 변수를 지정하고 싶다면 굳이 두줄로 적어야할까?
    • 정답은 int x = 0, y = 5; 이런 식으로 " , "를 통해서도 한줄에 작성할수 있다
  • 변수의 종류
    • 변수의 종류에는 클래스 변수, 인스턴스 변수, 지역 변수가 있다 
    • 이중 지역변수는 0으로 자동초기화가 되지 않기 때문에 직접 우리가 초기화를 꼭! 해주어야 한다

 

변수의 값 읽어오기

  • 변수의 값이 필요한 곳에 변수의 이름을 적는다.
int year = 0, age = 14;
    year = age + 2000;
    이런 식으로 적혀있다면 age라고 적혀있는 변수 이름을 찾고 거기에 해당하는 정보인 14를 불러온다
    year = 14 + 2000;
    year = 2014;
    그럼 year이름의 변수의 정보는 2014가 저장된다
    
    
    이런 정보는 어떻게 저장될까?
    age = age + 1;
    age = 14 + 1;
    age = 15;
    가 될것이고 age라는 변수를 가진 저장장소에 정보에 있는 14는 지워지고 15로 저장될 것이다

 

변수의 타입

  • 변수의 타입은 저장할 값의 타입에 의해 결정된다.
    • 우리가 저장했던 int age;는 int값만이 저장된다. 거기에 다른 타입을 저장하려하면 에러를 발생시킨다
  • 저장할 값의 타입과 일치하는 타입으로 변수를 선언해야 한다
    • char ch = '가' ;
    • double pi = 3.14 ;

 

값의 타입

  • 기본형(Primitive type)
    • 문자형 : 하나의 문자를 저장하는데 사용한다 
      • char( 0 ~ 65535 )
    • 숫자
      • 정수형 : 주로 int, long을 사용한다
        • byte( -128 ~ 127 ) : 이진데이터를 다루는데 사용한다
        • Short( -32,768 ~ 32,767 ) : C언어와의 호환성을 위해 추가되었다
        • int( -20억 ~ 20억 ) : default 값이다
        • long( - 800경 ~ 800경 )
        • 참고로 800경보다 많은 수를 다룬다면 BigInteger를 사용하면 된다.
      • 실수형
        • float 
          • 나타낼수 있는 범위 : -3.4E38 ~ 3.4E38 
          • 나타낼수 없는 범위 : -1.4E-45 ~ 1.4E-45
          • int와 같은 4byte의 범위를 가진 float는 어떻게 이렇게 큰 수를 담을 수 있는걸까
            • 일반적인 것과 다르게 지수(8Bit)와 가수(23Bit)를 따로 보관하기 때문이다
            • 정밀도(오차 없는 자릿수) : 7자리
        • double : default 값이다
          • 나타낼수 있는 범위 : -1.8E308 ~ 1.8E308 
          • 나타낼수 없는 범위 : -4.9E-324 ~ 4.9E-324
          • 이것도 같은 8byte를 가진 long보다 훨씬 크다 이유는 float의 원인과 같다
            • 정밀도(오차 없는 자릿수) : 15자리
    • 논리형(boolean) : 조건식과 논리적 계산에 사용된다
      • true
      • false
  1bit 는 2진수 1의 자리, 1byte = 8 Bit
1 Byte 2 Byte 4 Byte 8 Byte
논리형 Boolean      
문자형   Char
(유니코드 = 2Byte)
   
정수형 byte short int long
실수형     float double
  • 참조형(Reference type)
    • 기본형을 제외한 나머지(String, System 등)
      • 갯수는 무한하다
    • 메모리 주소를 저장한다( 4 byte(4GB) 또는 8 byte(1600만 TB) )
      • 실질적으로 사용할 수 있는양은 4 byte(32 Bit) = 2GB, 8 byte(64Bit) = TB단위 이다
      • 객체의 주소를 저장한다

 

상수, 리터럴

  • 상수 - 한 번만 값을 저장 가능한 변수를 뜻한다
    • 여기서 변수와의 차이점은 변수는 값이 변경을 할 수 있었지만 상수는 아니다. 상수는 바꿀수 없는것이다
    • 그럼 어떻게 값을 저장하면 더 이상 교환할 수 없게 만들수 있을까? 바로 final을 사용하는것이다.
기존의 변수
int score = 100;  -> score = 100;
    score = 200;  -> score = 200;
    
상수(final)의 사용
final int MAX = 100; -> MAX = 100;
          MAX = 200; -> 에러;
  • 리터럴 - 그 자체로 값을 의미하는것 (기존의 상수)
    • 너무 어렵게 생각하지 말자, 간단히 말해서 상수인데 자바내에 상수를 다른 의미로 사용하고 있기때문이다 그래서 원래 상수의 의미를 리터럴로 사용했다 라고 생각하면 된다 
    • 접두사와 접미사
boolean power = true; // boolean값은 true or false 이다

char ch = 'A' // char는 문자형을 뜻하고 ' ' 로 표시한다
String str = "ABC" // String은 문자열을 뜻하고 " " 로 표시한다 "A"처럼 한글자만 들어가도 문자열이다

byte b = 127; // 접미사가 아무것도 없다면 int로 인식하지만 int의 숫자가 byte의 범위를 벗어나면 오류가 발생한다

int i = 0b0101 // 2진수
int ten = 100 // 10진수
int oct = 0100 // 8진수
int hex = 0x100 // 16진수

long l = 10_000_000_000L; // int형 범위를 넘기는 숫자는 꼭 L을 붙여주어야하고 long타입으로 지정해주어야 한다
long l = 100L; // L를 때면 int로 읽히지만 long의 범위로 들어와있기 때문에 괜찮다

float f = 3.14f; // f를 생략하면 자동으로 double타입으로 변환되기 때문에 오류를 발생한다
double d = 3.14d; // d는 생략해도 double로 자동으로 인식하기 때문에 괜찮다
  • 변수와 리터럴의 타입 불일치
    1. 범위가 변수 > 리터럴 인 경우는 괜찮다
      • int i = 'A';  // int > char , 하지만 int는 정수형이기 때문에 A를 65로 읽는다
      • long l = 123; // long > int
      • double d = 3.14f; // double > float
    2.  범위가 변수 < 리터럴 인 경우는 에러를 발생한다
      • int i = 30_0000_0000; // int의 범위를 벗어난다
      • long l = 3.14f // long < float 이기 때문에 에러
      • float f = 3.14 // float < double 이기 때문에 에러
    3. byte, short 변수에 int 리터럴 저장가능
      • byte b = 100; // byte의 범위에 벗어나지 않으면 저장할 수 있다.

 

문자와 문자열

char ch = 'A' // 홑따옴표로 묶는 문자형
char ch = 'AB' // 두개 이상의 문자가 들어가면 에러

String str = "ABC" // 두개 이상의 문자형을 넣기위해서는 String으로 하고 쌍따옴표 사용으로 문자열을 만든다
String s = "A" // String은 문자가 한개만 있어도 생성이 가능하다
String s = ""; // 이것 처럼 빈 문자열또한 가능하다
char ch = ''; // 하지만 char타입의 빈 문자는 오류를 발생시킨다

String s1 = "A" + "B" // "AB"로 나온다

"" + 7 = "7" // ""를 앞에 붙이면 뒤에 나오는 것들이 문자열로 변환된다는 것을 알 수 있다.
"" + 7 + 7 = "77" // 왼쪽부터 계산하여 문자열에 추가가 되는 방식이다
7 + 7 + "" = "14" // 이번엔 쌍따옴표가 가장 오른쪽에 있기 때문에 앞에서 숫자가 계산되고 그 후 문자열에 넣는것이다.

정리
문자열 + any type => 문자열
any type + 문자열 => 문자열

※String 에 대한 짧은 상식

  • String은 다른 타입과는 달리 원래 클래스이다 그래서 원래는 String s2 = new String("AB")로 작성해야 옮바른 작성이지만 워낙 자주 사용하는탓에 String s1 = "AB"또한 허용한 것이다.

 

두 개의 변수의 값 교환

두개의 변수를 교환할때 중요한것은 바로 비어있는 공간이다. 상식적으로는 그저 주고 받으면 그만이지만 컴퓨터 프로그램답게 항상 어떠한 정보는 어딘가에 저장되어 있어야한다. 그렇지 않다면 그저 없는 수가 되는것이다. 그래서 빈 공간이 필요한 것이다.

int x = 10; y = 20;
int tmp; // 빈공간

tmp = x; // 빈 공간에 x정보를 저장해두고
x = y;   // x에 값을 20으로 새로 정의하고
y = tmp; // x의 값을 저장해둔 tmp값을 y에 값으로 변경해주면된다

그럼 x와 y는 값이 바뀌었다가 되는것이다

 

타입간 변환 방법

  • 문자(char)와  숫자 간의 변환
    • 숫자 + '0' = 문자로 전환
    • 문자 - '0' = 숫자로 전환
    • 문자0 을 연산해주는것이 중요
  • 문자열(String)로 변환
    • 숫자 + "" = 문자열로 전환
    • 문자 + "" = 문자열로 전환
    • 두개다 ""를 더해주면 된다
  • 문자열(String)을 숫자로 변환
    • "3"을 변환하려면 Integer.parseInt("3") 이라고 넣어준다면 숫자3으로 변환된다
    • "3.4" 를 변환하려면 Double.parseDouble("3.4")라고 적어주면 double 3.4 로 변환된다
    • 문자열 "3"을 문자로 바꾸려면 "3".charAt(0)을 하면 문자3이 된다
public static void main(String args[]) {
    String str = "3";
    
    System.out.println(str.charAt(0) - '0')        // 문자 - 문자 = 숫자 3
    System.out.println('3' - '0' + 1);             // 문자 - 문자 + 숫자 = 숫자 4
    System.out.println(Integer.parseInt("3") + 1); // 숫자 + 숫자 = 숫자 4
    System.out.println("3" + 1);                   // 문자열 + 숫자 = 문자열 31( 1이 문자열로 변환 )
    System.out.println(3 + '0');                   // 숫자 + 문자 = 숫자 51( '3'은 51 )
}