자바의 정석 | Ch 2 - 변수(Variable)
by 무작정 개발1. 변수(variable)
1.1 변수(variable)란?
수학에서는 '변하는 수'라고 정의하지만 프로그래밍 언어에서는 변수란 값을 저장할 수 있는 메모리상의 공간을 의미
1.2 변수의 선언과 초기화
변수타입이란?
'변수 타입' 은 변수에 저장될 값이 어떤 '타입(type)'인지를 지정하는 것이다. 저장하고자 하는 값의 종류에 맞게 변수의 타입을 선택해서
적어주면 된다. Java는 정수형, 실수형, 문자형 등 다양한 타입을 제공한다.
변수 이름이란?
'변수 이름'은 말 그대로 변수에 붙인 이름이다. 변수는 '값을 저장할 수 있는 메모리 공간'이므로 변수의 이름은 메모리 공간에
이름을 붙여주는 것이다. 그리고 같은 이름의 변수가 여러 개 존재해서는 안된다. 서로 구별될 수 있어야 하기 때문이다.
변수의 초기화
변수를 선언한 이우부터는 사용할 수 있지만 그전에 반드시 변수를 초기화해야 한다.
Why? -> 메모리는 여러 프로그램이 공유하는 자원이므로 전에 다른 프로그램에 의해 저장된 '알 수 없는 값이 남아있을 수 있기 때문이다.
변수에 값을 저장할 때는 대입 연산자 '='를 이용한다. 수학에서는 양쪽 값이 같다는 의미이지만, Java에서는 오른쪽의 값을 왼쪽(변수)에
저장하라는 뜻이다.
ex) int age = 25; // 변수 age를 선언하고 25로 초기화한다. ---> 변수의 초기화란, 변수를 사용하기 전에 처음으로 값을 저장하는 것
int는 변수 타입 / age는 변수 이름
//예제 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로 초기화하였다.
두 변수의 값 교환하기
//예제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'와 같이 작은따옴표로 문자 하나를 감싼 것을 '문자 리터럴'이라고 한다. 두 문장 이상은 큰 따옴표로 감싸야하며 '문자열 리터럴'이라 함.
//예제 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)로 출력 |
//예제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를 사용함.
}
}
//예제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 타입의 값으로 반환
위의 내용을 이해했으면 하단 예제를 풀어보자!
//예제 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타입의 변수는 단 하나의 문자만을 저장할 수 있습니다.
//예제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\) |
//예제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'이므로 이 값이
무한히 반복된다.
//예제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을 선택해야 한다.
//예제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);
}
}
//예제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타입으로 형 변환
//예제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 정수형 간의 형 변환
큰 타입에서 작은 타입으로의 변환에서는 값 손실이 발생할 수 있다.
//예제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으로 채운다.
//예제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
'Language > Java' 카테고리의 다른 글
자바의 정석 | Ch 06 - 객체지향프로그래밍1-1 (0) | 2021.12.16 |
---|---|
자바의 정석 | Ch 05 - 배열 Array (0) | 2021.12.15 |
자바의 정석 | Ch 04 - 조건문과 반복문 (0) | 2021.12.15 |
자바의 정석 | Ch 03 - 연산자(Operator) (0) | 2021.12.15 |
자바의 정석 | Ch 01 - 자바를 시작하기 전에 (2) | 2021.12.13 |
블로그의 정보
무작정 개발
무작정 개발