자바의 정석 | Ch 2 - 변수(Variable)
by 무작정 개발1. 변수(variable)
1.1 변수(variable)란?
수학에서는 '변하는 수'라고 정의하지만 프로그래밍 언어에서는 변수란 값을 저장할 수 있는 메모리상의 공간을 의미
1.2 변수의 선언과 초기화
변수타입이란?
'변수 타입' 은 변수에 저장될 값이 어떤 '타입(type)'인지를 지정하는 것이다. 저장하고자 하는 값의 종류에 맞게 변수의 타입을 선택해서
적어주면 된다. Java는 정수형, 실수형, 문자형 등 다양한 타입을 제공한다.
변수 이름이란?
'변수 이름'은 말 그대로 변수에 붙인 이름이다. 변수는 '값을 저장할 수 있는 메모리 공간'이므로 변수의 이름은 메모리 공간에
이름을 붙여주는 것이다. 그리고 같은 이름의 변수가 여러 개 존재해서는 안된다. 서로 구별될 수 있어야 하기 때문이다.
변수의 초기화
변수를 선언한 이우부터는 사용할 수 있지만 그전에 반드시 변수를 초기화해야 한다.
Why? -> 메모리는 여러 프로그램이 공유하는 자원이므로 전에 다른 프로그램에 의해 저장된 '알 수 없는 값이 남아있을 수 있기 때문이다.
변수에 값을 저장할 때는 대입 연산자 '='를 이용한다. 수학에서는 양쪽 값이 같다는 의미이지만, Java에서는 오른쪽의 값을 왼쪽(변수)에
저장하라는 뜻이다.
ex) int age = 25; // 변수 age를 선언하고 25로 초기화한다. ---> 변수의 초기화란, 변수를 사용하기 전에 처음으로 값을 저장하는 것
int는 변수 타입 / age는 변수 이름
java//예제 2-1/ch2/VarEx1.java public class VarEx1 { public static void main(String[] args) { int year = 0; int age = 14; System.out.println(year); System.out.println(age); year = age + 2000; // 변수 age의 값에 2000을 더해 변수 year에 저장 age = age + 1; // 변수 age에 저정된 값을 1 증가시킨다. System.out.println(year); System.out.println(age); } }
실행 결과 : 0
14
2014
15
두 개의 변수 age와 year를 선언한 다음, 값을 저장하고 출력하는 간단한 예제이다. 변수 year, age를 각각 0과 14로 초기화하였다.
두 변수의 값 교환하기
java//예제2-2/초2/VarEx2.java public class VarEx2 { public static void main(String[] args) { int x = 10 , y = 20; int tmp = 0; System.out.println("x:" + x + " y:" + y); tmp = x; //x는 10인데 10을 tmp에 넣어준다 -> tmp=10 x = y; // y값을 x에 넣어준다. x = 20 y = tmp; // tmp값을 y에 넣어준다. 위에서 tmp=10이므로 y=10 System.out.println("x:" + x + " y:" + y); //실행결과 x:10 y:20 } // y:20 x:10 }
1.3 변수의 명명규칙
'변수의 이름'처럼 프로그래밍에서 사용하는 모든 이름을 '식별자'라고 하며, 식별자는 같은 영역 내에서 서로 구분(식별)될 수 있어야 한다.
그리고 식별자를 만들 때는 다음과 같은 규칙을 지켜야 한다.
1. 대소문자가 구분되며 길이에 제한이 없다.
- True와 true는 서로 다른 것으로 간주된다.
2. 예약어를 사용해서는 안 된다.
- true는 예약어라서 사용할 수 없지만, True는 사용 가능하다.
3. 숫자로 시작해서는 안 된다.
- top 10은 허용되지만, 10 top는 허용되지 않는다.
4. 특수문자는 '_'와 '$' 만을 허용한다.
- $harp은 허용되지만, S#arp은 허용되지 않는다.
2. 변수의 타입
변수의 타입의 종류는 크게 '문자와 숫자'로 나눌 수 있고, 숫자는 '정수와 실수'로 나눌 수 있다.

이러한 값의 종류에 따라 값이 저장될 공간의 크기와 저장 형식을 정의한 것이 자료형이다.
기본형과 참조형
자료형은 크게 '기본형'과 '참조형' 2가지로 나눌 수 있고, 기본형 변수는 실제 값(data)을 저장 하하는 반면, 참조형 변수는 어떤 값이 저장되어 있는 주소(memory address)를 값으로 갖는다. Java에서는 C언어와 달리 참조형 변수 간의 연산을 할 수 없어 실제 연산에서는
기본형 변수만 사용한다.
2.1 기본형(primitive type)
기본형에는 모두 8개의 타입(자료형)이 있으며, 크게 논리, 문자, 정수, 실수형으로 구분
<기본형의 종류>
분류 | 타입 |
논리형 | boolean |
true와 false 중 하나를 값으로 갖으며, 조건식과 논리적 계산에 사용된다. | |
문자형 | char |
문자를 저장하는데 사용되며, 변수에 하나의 문자만 저장할 수 있다. | |
정수형 | byte, short, int , long |
정수를 저장하는데 사용되며, 주로 int가 사용된다. byte는 이진 데이터를 다룰 때 사용되며, short는 C언어와의 호환을 위해서 추가되었다. |
|
실수형 | float, double |
실수를 저장하는데 사용되며, 주로 double이 사용된다. |
<기본형의 종류와 크기>
종류/크기 | 1 byte | 2 byte | 3 byte | 4 byte |
논리형 | boolean | |||
문자형 | char | |||
정수형 | byte | short | int | long |
실수형 | float | double |
boolean은 ture/false 2가지 값만 표현
2.2 상수와 리터럴(constant & literal)
'상수(constant)'는 변수와 마찬가지로 '값을 저장할 수 있는 공간'이지만, 변수와 다르게 한번 값을 저장하면 다른 값으로 변경할 수 없다.
상수를 선언하는 방법은 변수와 동일하고, 변수의 타입 앞에 'final'을 붙여주기만 하면 된다.
final int MAX_SPEED = 10; //상수 MAX_SPEED를 선언 & 초기화
리터럴(literal)
프로그래밍에서는 상수를 '값을 한 번 저장하면 변경할 수 없는 저장공간'으로 정의하였기 때문에 이와 구분하기 위해 상수를 '리터럴'이라는 용어로 부른다.
int year = 2021; //year는 변수, 2021은 리터럴
final int MAX_VALUE = 100; // MAX_VALUE는 상수, 100은 리터럴
문자 리터럴과 문자 리터럴
'A'와 같이 작은따옴표로 문자 하나를 감싼 것을 '문자 리터럴'이라고 한다. 두 문장 이상은 큰 따옴표로 감싸야하며 '문자열 리터럴'이라 함.
java//예제 2-3/ch2/StringEx.java public class StringEx { public static void main(String[] args) { String name = "Ja" + "va"; String str = name + 8.0; System.out.println(name); // 결과 : Java System.out.println(str); // 결과 : Java8.0 System.out.println(7 + " "); System.out.println(" " + 7); System.out.println(7 + ""); System.out.println("" + 7); System.out.println("" + ""); System.out.println(7 + 7 + ""); System.out.println("" + 7 + 7); System.out.println(" " + 7 + 7); } }
2.3 형식화된 출력 - printf()
printf()는 println()과 다르게 같은 값이라도 다른 형식으로 출력하고 싶을 때 사용한다. 예를 들어 소수점 둘째 자리까지만 출력하거나,
정수를 16진수나 8진수로. 출력한다던가, 이럴 때 printf()를 사용하면 된다.
prinf()는 '지시자'를 통해 변수의 값을 여러 가지 형식으로 변환하여 출력하는 기능을 가지고 있다. '지시자'는 값을 어떻게 출력할 것인지를 지정해주는 역할을 한다.
<자주 사용되는 printf()의 지시자>
지시자 | 설명 |
%b | 불리언(boolean)형식으로 출력 |
%d | 10진(decimal)정수의 형식으로 출력 |
%o | 8진(octal)정수의 형식으로 출력 |
%x, %X | 16진(hexa-decimal)정수의 형식으로 출력 |
%f | 부동 소수점(floating-point)의 형식으로 출력 |
%e, %E | 지수(exponent)표현식의 형식으로 출력 |
%c | 문자(character)로 출력 |
%s | 문자열(string)로 출력 |
java//예제2-4/ch2/PrintfEx1.java ublic class PrintfEx1 { public static void main(String[] args) { byte b = 1; short s = 2; char c = 'A'; int finger = 10; long big = 100_000_000_000L; //long big = 100000000000 long hex = 0xFFFF_FFFF_FFFF_FFFFL; int octNum = 010; int hexNum = 0x10; int binNum = 0b10; System.out.printf("b = %d%n", b); // b = 1 System.out.printf("s = %d%n", s); // s = 2 System.out.printf("c = %c, %d %n", c, (int)c); // c = A, 65 %d가 왜 65가 나왔냐? 영문 대문자 'A'는 숫자 65를 뜻함 System.out.printf("finger = [%5d]%n", finger); // finger = [ 10] System.out.printf("finger = [%4d]%n", finger);//finger = [ 10] System.out.printf("finger = [%3d]%n", finger);//finger = [ 10] System.out.printf("finger = [%d]%n", finger);// finger = [10] System.out.printf("finger = [%-5d]%n", finger);// finger = [10 ] System.out.printf("finger = [%05d]%n", finger); // finger = [00010] System.out.printf("big = %d%n", big);// big = 100000000000 System.out.printf("hex = %x %n", hex); // hex = ffffffffffffffff %x는 16진정수의 형식으로 출력 System.out.printf("hex = %#x %n", hex);// hex = 0xffffffffffffffff %x는 16진정수의 형식으로 출력 // #은 접두사 0x가 붙는다 System.out.printf("hex = %#X %n", hex);// hex = 0XFFFFFFFFFFFFFFFF %X는 16진정수의 형식으로 출력(대문자로출력) System.out.printf("octNum = %o, %d%n",octNum, octNum);// octNum = 10, 8 %o는 8진정수의 형식으로 출력 // 8진수 10, 10진수 8 System.out.printf("hexNum = %x, %d%n", hexNum, hexNum);// hexNum = 10, 16 System.out.printf("binNum = %s, %d%n", Integer.toBinaryString(binNum), binNum);// binNum = 10, 2 //10진수를 2진수로 출력해주는 지시자는 없어 정수를 2진 문자열로 변환해주는 Integer.toBinaryString(int i)를 사용하고 이 메서드는 정수를 //2진수로 변환해서 문자열로 반환하므로 지시자 %s를 사용함. } }
java//예제2-5/ch2/PrintEx2.java public class PrintfEx2 { public static void main(String[] args) { String url = "www.codechobo.com"; float f1 = .10f; float f2 = 1e1f; float f3 = 3.14e3f; double d = 1.23456789; System.out.printf("f1 = %f, %e, %g%n", f1, f2, f3); System.out.printf("f2 = %f, %e, %g%n", f2, f2, f2); System.out.printf("f3 = %f, %e, %g%n", f3, f3, f3); System.out.printf("d = %f%n", d); System.out.printf("d = %14.10f%n", d); //전체 14자리 중 소수점 10자리 System.out.printf("[12345678901234567890]%n"); System.out.printf("[%s]%n", url); System.out.printf("[%20s]%n", url); System.out.printf("[%-20s]%n", url);//왼쪽 정렬 System.out.printf("[%.8s]%n", url);// 왼쪽에서 8글자만 출력 } }
2.4 화면에서 입력받기 - Scanner
지금까지 화면에 출력만 했지만 Scanner를 써서 입력받는 방법을 사용해봅시다.
Scanner클래스를 사용하려면, 아래의 한 문장을 상단에 추가해줘야 한다.
import java.util.*; //Scanner클래스를 사용하기 위해 추가
그다음에 Scanner클래스의 객체를 생성한다.
Scanner scanner = new Scanner(System.in); // Scanner클래스의 객체를 생성
그리고 nextLine()이라는 메서드를 호출하면, 입력 대기 상태에 있다가 입력을 마치고 '엔터키'를 누르면 입력한 내용이 문자열로 반환된다.
String input = scanner.nextLine(); // 입력받은 내용을 input에 저장
int num = Integer.parseInt(input); // 입력받은 내용을 int 타입의 값으로 반환
위의 내용을 이해했으면 하단 예제를 풀어보자!
java//예제 2-6/ch2/ScannerEx.java import java.util.*; //Scanner를 사용하기 위해 추가 public class ScannerEx { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); // Scanner클래스의 객체를 생성 System.out.print("두자리 정수를 입력하세요 : "); String input = scanner.nextLine(); // 입력받은 내용을 input에 저장 int num = Integer.parseInt(input); //입력받은 문자열을 숫자로 변환 //입력받은 문자열을 숫자(int타입의 정수)로 변환하려면,Interger.parseInt() 메서드를 이용 System.out.println("입력내용 :" + input); System.out.printf("num = %d%n", num); } }
3. 진법
10진법, 2진법, 8 진법 등은 패스.
4. 기본형(primitive type)
앞의 2와 2.1에서보다 좀 더 깊게 기본형의 세부적인 내용을 다룬다.
4.1 논리형-boolean
논리형에는 'boolean' 1가지 밖에 없다. boolean형 변수에는 true와 false 중 하나를 저장할 수 있으며 기본값(default)은 false이다.
boolean power = true;
boolean checked = False; // 에러. 대소문자가 구분됨. ture 또는 false만 가능
4.2 문자형-char
문자형에는 'char' 1가지 밖에 없다. char타입의 변수는 단 하나의 문자만을 저장할 수 있습니다.
java//예제2-7/ch2/CharToCode.java public class CharToCode { public static void main(String[] args) { char ch = 'A'; // char ch = 65; int code = (int)ch; // ch에 저장된 값을 int타입으로 변환하여 저장 System.out.printf("%c = %d(%#X)%n", ch, code, code); char hch = '가'; System.out.printf("%c = %d(%#X)%n", hch, (int)hch, (int)hch); } //결과 A = 65(0x41) } // 가 = 44032(0XAC00)
실행결과를 보면 문자 'A'의 유니코드는 65, 문자 '가'의 유니코드는 44032라는 것을 알 수 있습니다.
특수 문자 다루기
' \t ' 는 실제로는 두 문자로 이루어져 있지만 한 문자(탭, tab)를 의미합니다. 하단의 표는 탭(tap)과 같이 특수한 문자를 어떻게 표현할 수 있는지 알려준다.
<특수문자를 표현하는 방법>
특수 문자 | 문자 리터럴 |
tab | \t |
backspace | \b |
form feed | \f |
new line | \n |
carriage return | \r |
역슬래쉬(\) | \\ |
작은따옴표 | \' |
큰따옴표 | \" |
유니코드(16진수)문자 | \u유니코드(ex: char a = '\u0041\) |
java//예제2-8/ch2/SpecialCharEx.java public class SpecialCharEx { public static void main(String[] args) { System.out.println('\'');// '''처럼 할수 없다. 결과 : ' System.out.println("abc\t123\b456"); //\b에 의해 3이 지워진다 / 결과: abc 123456 System.out.println("\n"); // 개형(new line)문자 출력하고 개행 / 결과 : 빈줄 출력 System.out.println("\"Hello\""); // 큰따옴표를 출력하려면 이렇게한다 / 결과 : "Hello" System.out.println("c:\\"); // 결과 : c:\ } }
4.3 정수형-byte, short, int, long
정수형에는 모두 4가지의 자료형이 있으며, 각 자료형이 저장할 수 있는 값의 범위가 서로 다르다.
byte(1byte) < short(2byte) < int(4byte) < long(8byte)
부호 있는 정수의 오버플로우
부호 없는 정수와 부호 있는 정수는 표현 범위 즉, 최댓값과 최솟값이 다르기 때문에 오버플로우가 발생하는 시점이 다르다. 부호가 없는 정수는 2진수로 '0000'이 될 때 오버플로우가 발생하고, 부호가 있는 정수는 부호 비트가 0에서 1이 될 때 오버플로우가 발생한다.
부호가 없는 정수의 경우 표현 범위가 '0~15'이므로 이 값이 계속 반복되고, 부호있는 정수의 경우 표현범위가 '-8~7'이므로 이 값이
무한히 반복된다.
java//예제2-9/ch2/OverflowEx.java public class OverflowEx { public static void main(String[] args) { short sMin = -32768; short sMax = 32767; char cMin = 0; char cMax = 65535; System.out.println("sMin = " + sMin); System.out.println("sMin-1" + (short)(sMin-1)); System.out.println("sMax = " + sMax); System.out.println("sMax+1" + (short)(sMax+1)); System.out.println("cMin = " + (int)cMin); System.out.println("cMin-1 = " + (int)cMax); System.out.println("cMax = " + (int)cMax); System.out.println("cMax+1= " + (int)++cMax); } }
실행결과: sMin = -32768
sMin-1 = 32767
sMax = 32767
sMax+1 = -32768
cMin = 0
cMin-1 = 65535
cMax = 65535
cMax+1 = 0
4.4 실수형-float, double
실수형은 실수를 저장하기 위한 타입으로 float와 double, 2가지가 있습니다. 연산속도의 향상이나 메모리를 절약하려면 float를 선택하고
, 더 큰 값의 범위라던가 더 높은 정밀도를 필요로 한다면 double을 선택해야 한다.
java//예제2-10/ch2/FloatEx1.java public class FloatEx1 { public static void main(String[] args) { float f = 9.123456878901234567890f; float f2 = 1.2345678901234567890f; double d = 9.12345678901234567890d; System.out.printf(" 123456789012345678901234%n"); System.out.printf("f : %f%n", f);//소수점 이하 6째자리까지 출력/7자리에서 반올림되서 출력된다. System.out.printf("f : %24.20f%n", f2); System.out.printf("f2 : %24.20f%n", f2); System.out.printf("d : %24.20f%n", d); } }
java//예제2-11/ch2/FloatToBinEx.java public class FloatToBinEx { public static void main(String[] args) { float f = 9.1234567f; int i = Float.floatToIntBits(f);//floatToIntBits()는 float타입값을 int타입값으로 해석해서 반환해준다. System.out.printf("%f%n", f); System.out.printf("%X%n", i); //16진수로 출력 } }
5. 형 변환
5.1 형 변환(캐스팅, casting)이란?
서로 다른 타입 간의 연산을 수행해야 하는 경우에 연산을 수행하기 전에 타입을 일치시켜야 하는데, 변수나 리터럴의 타입을 다른 타입으로
변환하는 것을 '형 변환(casting)'이라 한다.
형 변환이란, 변수 또는 상수의 타입을 다른 타입으로 변환하는 것
5.2 형변환 방법
형변환 방법은 형 변환하고자 하는 변수나 리터럴의 앞에 변환하고자 하는 타입을 괄호와 함께 붙여주기만 하면 된다.
(타입) 피연산자
double d = 85.4;
int score = (int) d; // double타입의 변수 d를 int타입으로 형 변환
java//예제2-12/ch2/CastingEx1.java public class CastingEx1 { public static void main(String[] args) { double d = 85.4; int score = (int)d; System.out.println("score = " + score); //결과 : score = 85 System.out.println("d = " +d); // 결과 : d = 85.4 } }
기본형(primitive typte)에서 boolean을 제외한 나머지 타입들은 서로 형 변환이 가능하다.
@ float타입의 값을 int타입으로 변환할 때 소수점 이하의 값은 반올림이 아닌 버림 처리가 된다.@
5.3 정수형 간의 형 변환
큰 타입에서 작은 타입으로의 변환에서는 값 손실이 발생할 수 있다.
java//예제2-13/ch2/CastingEx2.java public static void main(String[] args) { int i = 10; byte b = (byte)i; System.out.printf("[int -> byte] i=%d -> b=%d%n", i, b); i = 300; b = (byte)i; System.out.printf("[int -> byte] i=%d -> b=%d%n", i, b); b = 10; i = (int)b; System.out.printf("[byte -> int] b=%d -> i=%d%n", b, i); b = -2; i = (int)b; System.out.printf("[byte -> int] b=%d -> i=%d%n", b, i); System.out.println("i = " + Integer.toBinaryString(i)); } } //결과 //[int -> byte] i=10 -> b=10 //[int -> byte] i=300 -> b=44 //[byte -> int] b=10 -> i=10 //[byte -> int] b=-2 -> i=-2 //i = 11111111111111111111111111111110
5.4 실수형 간의 형 변환
실수형에서도 정수형처럼 작은 타입에서 큰 타입으로 변환하는 경우, 빈 공간을 0으로 채운다. float타입의 값을 double으로 변환하는
경우, 지수(E)는 float의 기저인 127을 뺀 후 double 기저인 1023을 더해서 변환하고, 가수(M)는 float의 가수 23자리를 채우고 남은
자리를 0으로 채운다.
java//예제2-14/ch2/CastingEx3.java public class CastingEx3 { public static void main(String[] args) { float f = 9.1234567f; double d = 9.1234567; double d2 = (double)f; System.out.printf("f = %20.18f\n", f); System.out.printf("d = %20.18f\n", d); System.out.printf("d2 = %20.18f\n", d2); } } //결과 // f = 9.123456954956055000 // d = 9.123456700000000000 // d2 = 9.123456954956055000
블로그의 정보
무작정 개발
무작정 개발