02_변수(Variable)
변수(Variable): 메모리(RAM)에 값을 기록하기 위한 공간, 값을 담아 두는 상자(언제든지 변할 수 있음)
소스코드(.java)는 하드디스크(HDD)에 저장됨 => 프로그램(정적인 상태)
기계어(.class)가 실행된 형태를 메모리(RAM)에 로딩 => 프로세스(동적인 상태)
*자바의 문법
1. 자바에서 문자열은 ""(쌍따옴표) 안에 표기한다.
2. 자바에서 곱셈 연산은 x 표시가 아닌 * 표시로 표현한다.
3. 자바에서의 서로 다른 종류의 값들을 연이어 붙이고 싶을 때에는 + 표시로 표현한다.
4. 자바에서의 = 표시는 "대입하겠다" (같다가 아님! 같다의 의미는 ==)
*변수를 사용하는 이유
1. 변수는 우선적으로 값에 의미를 부여할 목적으로 사용됨(가독성 향상 = 변수의 이름이 값의 의미를 손쉽게 알게 해 줌)
2. 단 한 번 값을 기록해 두고 필요할 때마다 계속 사용할 목적으로 사용됨(재사용성 좋아짐)
3. 유지보수를 보다 편하게 할 수 있음
변수의 선언: 메모리 공간에 데이터를 저장할 수 있는 공간을 할당하는 것
=> 나 이제 공간(메모리 공간) 만들어서 얘(변수) 담는 데 쓸 거야~ = 땅따먹기 개념
=> [ 표현법 ] 자료형 변수명; // 자료형에 따라 땅따먹을 수 있는 크기가 다르기 때문에 자료형 적어 줘야 함
int pay = 10000; // 선언과 동시에 값을 넣음
int pay; // 선언, 나 이제부터 int 자료를 pay라는 변수에 넣을 거야!
자료형(변수 타입) = 자바에서는 기본 9가지(String 참조형, 나머지 8가지 타입은 기본형)
내가 앞으로 변수라는 상자에 어떤 값을 담아낼지, 어떤 종류의 값을 담아낼지 구분해 주는 개념
즉, 값의 종류를 나타내는 개념
1. 논리 - 주어진 문제에 대해 예/아니오(True/False)로 답할 수 있는 개념
표현식: boolean[불리언] 1byte
true / false => 3 + 5 < 1(3 + 5가 1보다 작습니까?) 처럼 연산식으로도 표현 가능
ex) boolean isXXX; // isXXX = 불리언 자료형의 기본 변수명! ~가 뭐니?(트루니 펄스니)의 뜻
2. 문자
2-1) 문자: 문자 1개(작은따옴표 ' ')
표현식: char 2byte
2-2) 문자열: 문자열 (큰따옴표 " ") -> "a" 문자 한 개라도 큰따옴표에 묶이면 문자열임
표현식: String 참조형 // String 첫 글자 대문자, 표면상 size 4byte이나 문자열의 크기를 미리 계산할 수 없으므로 크기는 참조형
3. 숫자
3-1) 정수형 - 소수점이 없는 수(1, 2, 3, ..., 0, -1, -2, ...)
표현식: byte 1byte, short 2byte, int 4byte(cpu 기본 연산 사이즈가 4byte이기 때문에 int가 정수형 대표임), long 8byte
3-2) 실수형 - 소수점이 있는 수(1.1, 1.2, 1.9999, -1.4, 0.0, 1.0 눈에 보이는 소수점 있으면 실수)
표현식: float 4byte(소수점 아래 7자리까지 표현 가능), double 8byte(소수점 아래 15자리까지 표현 가능, 더 정밀한 표현 가능해서 double이 실수형 대표임)
사이즈는 정수의 표현 범위를 지정할 수 있는 개념임
= 사이즈가 클수록 내가 담을 수 있는 표현 범위가 넓어짐
이클립스 단축키
ctrl + m: 코딩 외 화면 숨기기, 나타내기(Navigator, Console 등)
*변수 선언 시 주의할 점
1. 변수명은 소문자로 시작하게끔 이름 지어 줄 것(자바 명명 규칙에 따름, 단! 낙타표기법 지키기)
2. 같은 영역({}) 안에서는 동일한 변수명으로 선언 불가함
3. 해당 영역({}) 에 선언된 변수는 해당 영역 안에서만 사용 가능
=> 다른 메소드에서는 사용 불가(지역변수 개념)
<자료형에 대한 개념>
<기본 자료형 8가지>
1. 논리형 (논리값 = true / false)
boolean isTrue; // 1byte짜리 빈 상자가 만들어짐
2. 숫자형
2_1. 정수형
byte bNum; // 1byte (정수 -128 ~ 127까지만 담을 수 있음, 256개)
short sNum; // 2byte (정수 -32768 ~ 32767까지만 담을 수 있음)
int iNum; // 4byte (정수 -21억xx ~ 21억xx) => 정수형 자료형 중에서 기본 (CPU는 연산 시 4byte 단위로 처리하기 때문)
long lNum; // 8byte (제일 많은 범위의 수를 표현 가능)
2_2. 실수형
float fNum; // 4byte => 소수점 아래 7자리까지 표현 가능
double dNum; // 8byte => 소수점 아래 15자리까지 표현 가능, 실수형 자료형 중에서 기본 (더 정밀한 표현이 가능하기 때문)
3. 문자형
char ch; // 2byte => 문자 하나가 담김
----- 여기까지 총 8개의 기본 자료형 -----
<참조 자료형 1가지>
4. 문자열형
String str; // 표면상 4byte => 문자열의 길이는 가늠할 수 없기 때문에 4byte짜리 상자에 실제 값이 담기지는 않음!
----- 여기까지 총 9개의 빈 상자가 생성됨 -----
*변수에 값을 대입한다
변수에 값을 담기 == 빈 상자에 담기
[ 표현법 ] 변수명 = 값;
대입 연산자 실행 순서 int pay = 10000;
first: int pay
참조형이라면? 메모리(RAM)의 Stack 영역에 빈 상자 생김
second: 10000
참조형이라면? 메모리(RAM)의 Heap 영역에 빈 상자 생기고 값 입력되고 주소지 부여
third: =
참조형이라면? Stack영역에 heap 영역의 주소지를 대입함
isTrue = true;
bNum = 1;
sNum = 2;
iNum = 4;
lNum = 8L; // L, l: long type임을 알려 주기 위해서 쓰는 것! (대소문자 상관없으나 대문자 권장)
fNum = 4.0f; // f: float type임을 알려 주기 위해서 "반드시" 써야 함
dNum = 8.0;
ch = 'A'; // 문자는 반드시 '' (홑따옴표) 안에 작성해야 한다
str = "ABC"; // 문자열은 반드시 "" (쌍따옴표) 안에 작성해야 한다
출력값
isTrue :true
bNum: 1
sNum: 2
iNum: 4
lNum: 8
fNum: 4.0
dNum: 8.0
ch: A
str: ABC
변수 하나당 하나의 값만 담길 수 있음!
비트(bit): 1 아니면 0 한 개를 나타내는 단위, 컴퓨터가 나타내는 데이터의 저장 최소 단위로서 2진수 값 하나를 저장할 수 있는 메모리 공간을 의미
*이진수: 숫자 단 두 개(0, 1)만으로 모든 수를 표현
바이트(byte): 8bit = 1byte, 데이터 처리 또는 문자의 최소 단위로서 8개의 비트가 모여 하나의 바이트가 구성됨
'a', '!', '0' = 1byte
'김' = 2byte
데이터 오버플로우: 내가 담을 수 있는 값을 초과했을 때 나타나는 현상
ex) byte형은 -128~127까지 담길 수 있는데 128을 넣게 되면 127 + 1이므로 byte형 허용범위 최소값인 -128이 됨
ex) 시침과 분침이 있는 시계를 생각해 보자! 12에서 한 단계 더 가면 원래 13이지만 시계에서는 1이 됨, 1에서 하나 빼면 0이지만 시계에서는 12가 됨
11111111 = 십진수로 바꾸면 256인데 byte는 128까지만 담을 수 있다면서요?
=> 제일 앞 칸은 양수/음수를 나타내는 구간이므로 계산하지 않음
=> 양수일 경우, 00000000(0) ~ 01111111(127)
=> 음수일 경우, 10000000(-0 = 0) ~ 11111111(-128)
=> -128 - 1 = 127
<변수의 명명 규칙>
1. 대소문자가 구분되며 길이 제한이 없음
2. 예약어를 사용하면 안 됨
3. 숫자로 시작하면 안 됨
4. 특수문자는 _(언더바)와 $(달러표시)만 허용
5. 여러 단어 이름은 단어의 첫 글자를 대문자로 함
단, 첫 시작 글자는 소문자로 하는 것이 관례
*값 대입과 리터럴
값 대입: 생성한 변수(저장 공간)에 값을 대입하는 것, 대입 연산자(=) 사용
=> 변수는 한 개의 데이터만 보관하며 마지막에 대입한 값만 보관
int age = 10; // 초기화
age = 11; // 대입
age = 12; // 현재 age라는 변수에 담긴 값은 12
리터럴(값): 변수에 대입되는 값 자체
초기화: 대입은 대입인데 제일 처음에 대입되는 값, 변수를 사용하기 전에 처음으로 값을 저장하는 것
=> 지역변수는 반드시 초기화해야 함! 그러지 않으면 예상하지 못한 값이 튀어나올 수 있음
*문자열 표현
다른 자료형 + "문자열" => 문자열
"문자열" + 다른 자료형 => 문자열
"문자열" + "문자열" => "문자열문자열"
String str = "기차";
String str = new String("기차");
=> 두 개는 똑같은 표현법임! new: heap 영역에 빈 공간을 할당하겠다
*상수: 항상의 상! 한 번만 저장(기록)할 수 있는 메모리를 의미하며 초기화 이후 다른 데이터(값)을 대입할 수 없음
π = 3.14... 처럼 고정된 값을 의미함
=> [ 표현법 ] final 자료형 상수명 = 값;
=> 상수명은 관례상 대문자로 표시함
<사용자가 키보드로 입력한 값을 변수에 담는 방법>
자바를 통해서 사용자로부터 어떠한 값을 "입력"받으려면 자바에서 제공하는 java.util.Scanner 클래스를 이용해야 함
=> Scanner 클래스에서 제공하는 이미 만들어진 메소드를 호출만 잘해서 쓰면 됨
- 만약 지금 내가 작성 중인 클래스랑 다른 클래스에 있는 메소드를 호출하고 싶을 때,
* 1. 내가 호출하고자 하는 메소드가 있는 클래스를 대변할이름을 생성 (new)
* 2. 만약 그 클래스가 나랑 다른 패키지에 있을 경우 import 구문 추가해 줘야 함
* 3. 만들어진 대변할이름을 통해서 해당 메소드를 호출
Scanner sc = new Scanner(System.in); // System.in: 입력받은 값들을 바이트 단위로 읽어들이겠다
System.out.println("당신의 이름은 무엇입니까?: ");
// sc.next(); // 입력만 받고 끝
String name = sc.next(); // 변수 선언과 동시에 키보드로부터 입력받은 값을 대입
System.out.println(name);
이클립스 단축키
ctrl + F11: Run As Java Application
*처음으로 나온 공백(스페이스바, 띄어쓰기) 앞으로만 변수에 담김
=> 홍 길동으로 쳤을 때는 '홍'만 출력됨
next(): 사용자가 입력한 값 중에서 공백이 있을 경우 공백 이전까지만 입력을 받음
String name = sc.nextLine();
System.out.println(name);
nextLine(): 사용자가 입력한 값 중에서 개행이 있을 경우(엔터키를 누른 경우) 공백에 무관하게 한 줄 단위로 입력을 받는 메소드
Scanner 에서 제공하는 입력을 받아 주는 메소드들은 모두 엔터를 입력하기 전까지는 무작정 대기 상태!
*키보드로 값을 입력받기 위해 scanner를 이용할 때 종종 발생되는 문제
// 키보드로 값을 입력받을 때 종종 발생되는 문제
public void inputTest2() {
Scanner sc = new Scanner(System.in);
System.out.print("이름: ");
String name = sc.nextLine();
System.out.print("나이: ");
int age = sc.nextInt();
System.out.print("주소: ");
String address = sc.nextLine();
System.out.print("키: ");
double height = sc.nextDouble();
// 이름, 나이, 주소, 키
// xxx 님은 xx살이며, 사는 곳은 xxx이고, 키는 xxxcm입니다.
System.out.println(name + " 님은 " + age + "살이며, 사는 곳은 " + address + "이고, 키는 " + height + "cm입니다.");
}
}
System.out.print("주소: ");
String address = sc. nextLine(); // 이 코드가 씹혔다!!
왜일까?
nextLine()은 값 처리 후 남은 개행문자를 모두 사라지게 하는(버퍼를 비워 주는) 기능을 가지고 있음
그 외의 Scanner 입력용 메소드들은 (nextInt() 포함) 그런 거 없음
=> 즉, 이때 age를 처리했던 nextInt()가 버퍼에 개행 문자(\n)을 두고 갔고, address은 이 빈 문자열을 곧바로 대입시켜 버린 뒤, height로 넘어가 버림
*해결 방안
System.out.print("나이: ");
int age = sc.nextInt();
// 버퍼에 개행 문자가 남아 있는 상태
sc.nextLine(); // 입력만 받고 끝, 버퍼를 비우기 위해 얘를 추가해 줌!
// 버퍼가 비워진 상태
System.out.print("주소: ");
String address = sc.nextLine();
// nextLine() 메소드는 버퍼에서 "엔터" 이전까지의 모든 값을 가져온 후 버퍼를 비워 주는 역할(청소부)
// nextLine() 이외의 메소드들은 버퍼를 비워 주지 않음!
// => nextLine() 이외의 메소드를 호출할 경우 nextLine() 으로 버퍼를 비워 주자!
*Scanner 의 입력용 메소드들
문자열을 입력받고자 할 때: next(), nextLine()
정수값을 입력받고자 할 때: nextInt(), nextByte(), nextShort(), nextLong()
실수값을 입력받고자 할 때: nextDouble(), nextFloat()
논리값을 입력받고자 할 때: nextBoolean()
문자값을 입력받고자 할 때: 해당 메소드가 없음
*문자값으로 입력받고 싶을 때는?
System.out.print("성별(M/F): ");
char gender = 문자타입으로입력받고자함
*index: 색인, 순번
"apple" 문자열에서 a의 위치를 찾고 싶다!
01234 <- 컴퓨터 기준에서의 순서(0부터 시작함)
=> a 의 위치값 (index) 은 0
=> e 의 위치값 (index) 은 4
=> 우선적으로 nextLine() 메소드를 이용해서 문자열 형태로 입력받고,
입력받은 문자열로부터 0번째 인덱스의 문자값 하나만 추출하면, M/F로 성별 표시 가능하겠구나!
charAt(위치값): 문자열로부터 해당 위치값에 해당되는 문자 하나만 돌려 주는 메소드
[ 표현법 ] 문자열.charAt(위치값);
char gender = sc.nextLine().charAt(0);
// 먼저 문자열을 입력받은 후, 0번째 글자를 추출하여, gender에 대입
System.out.print("나이: ");
int age = sc.nextInt();
sc.nextLine(); // 버퍼 비우기
System.out.print("키: ");
double height = sc.nextDouble();
sc.nextLine();
// 이후에 실행할 코드 없어서 nextLine() 메소드 꼭 호출할 필요는 없지만 깔끔하게 습관 들이면 좋으니까~
System.out.println(name + " 님의 개인 정보");
System.out.println("성별: " + gender);
System.out.println("나이: " + age);
System.out.println("키: " + height);
*charAt(); 쓸 때 주의할 점
char gender = sc.nextLine().charAt(100); 라고 쓴다면?
=> 100번째 문자열은 없다!
=> StringIndexOutOfBoundsException: 추출하고자 하는 인덱스 값이 문자열의 길이를 넘어섰을 때 발생하는 오류
<형변환>
: 값의 자료형을 바꾸는 개념
1. 대입 연산자(=) 를 기준으로 왼쪽과 오른쪽은 같은 자료형이어야 함
=> 즉, 같은 자료형에 해당되는 값만 대입이 가능
=> 다른 자료형의 값을 대입하고자 한다면 "형변환"이 먼저 이루어져야 함 (필수)
왼쪽 = 오른쪽
값이 들어갈 공간 값으로 넣고 싶은 애(얘를 대입하기 전 형 변환 먼저 해 줌!)
[ 표현법 ] 자료형 변수명 = (바꿀자료형)값;
2. 같은 자료형끼리만 연산이 가능함
=> 즉, 다른 자료형끼리 연산을 수행하고 싶으면 적어도 둘 중에 하나는 "형변환"을 먼저 한 후 자료형을 맞춰 줘야 함(필수)
[ 표현법 ] 값 + (바꿀자료형)값;
3. 1, 2번 규칙을 합쳐서
같은 자료형끼리 연산이 이루어진 경우 그 연산 결과는 동일한 자료형으로 나옴
=> 즉, 같은 자료형끼리 연산이 이루어진 결과는 그 동일한 변수에만 대입 가능
ex) int result = int형숫자 + int형숫자;
<형변환의 종류>
1. 자동 형변환: 컴퓨터에서 자동으로 형변환이 진행되기 때문에 내가 직접 형변환을 할 필요가 없음
작은 바이트의 자료형 => 큰 바이트의 자료형
2. 강제 형변환(명시적 형변환-이름을 붙여 주며 형변환을 하겠다): (바꿀자료형)값처럼 바꿀 자료의 이름을 붙여 줌
: 자동 형변환이 되지 않아 직접 강제로 형변환 해야 하는 경우
[ 표현법 ] (바꿀자료형)값;
ex) 휴대폰 상자에 에어팟, 애플워치? 넣을 수 있음 = 자동 형변환
휴대폰상자에 패드, 노트북? 넣을 수 없음 = 강제 형변환
*(바꿀자료형): 형변환 "연산자" == Cast 연산자
**특이케이스 기준으로 잘 봐 놓을 것!
자동 형변환: 작은 바이트 => 큰 바이트로 자동 형변환되는 경우
public void autoCasting() {
// 1. int (4byte 정수) -> double (8byte 실수)
int i1 = 10;
double d1 = i1; // 자동으로 형변환이 되었다
// 10 -> 10.0
// double d1 = (double)i1; // 라고 써도(강제 형변환 해도) 무방하나 자동으로 해 주니까 굳이!
System.out.println("d1: " + d1);
int i2 = 12;
double d2 = 3.3;
double result2 = i2 + d2; // 12.0(자동 형변환) + 3.3 = 15.3
// double result2 = (double)i2 + d2; // 과 같다
System.out.println("result2: " + result2); // 15.3
// 2. int (4byte) -> long (8byte)
int i3 = 1000;
long l3 = i3;
// long l3 = (long)i3; //과 같다
System.out.println("l3: " + l3);
long l4 = 2000; // L을 안 붙였으므로 int 자료형의 2000으로 인식하나 long 타입의 상자를 만들면서 자동형변환 된 것
// long l4 = (long)2000; // 이것들과
// long l4 = 2000L; // 같다
// 특이 케이스 3. long (8byte) -> float (4byte)
// 정수가 실수로 담길 때에는 큰 사이즈의 정수가 작은 사이즈의 실수에 대입 가능
// 4byte float은 사실 long 형보다 담을 수 있는 범위가 더 크기 때문
// +질문 추가 답변: 실수는 소수점 아래를 더 많이 계산해 주기 때문에 사실 정수의 범위가 더 크다고 할 수 있다...?! 는 것처럼 답변해 주심 소수점의 계산 체계는 다르다고...!!
long l5 = 1000;
float f5 = l5; // 1000.0
// float f5 = (float)l5; // 와 같음
System.out.println("f5: " + f5);
// 특이케이스 4. char (2byte) <-> int (4byte) 양방향 형변환 가능
// char의 범위: 0 ~ 65535
// 각 문자마다 고유의 정수값이 정해져 있음
// => 해당 정수값들을 각 문자로 매칭시켜 주는 아스키코드표(0 ~ 127, 128가지의 문자를 나타낼 수 있음 - 영문자 대소문자 알파벳, 숫자, 특수문자)
// => 아스키코드표의 확장된 개념으로 유니코드표(0 ~ 65535, 65536가지의 문자를 나타낼 수 있음 - 영어, 숫자, 특수문자, 한글, 그 이외의 언어)
char ch = 65;
// char ch = (char)65; // 와 같음
System.out.println("ch: " + ch); // A => 아스키코드표 기준 65가 대문자 A
int num = 'A';
// int num = (int)'A'; // 와 같음
System.out.println("num: " + num); // 65
System.out.println('김'); // 김
System.out.println((int)'김'); // 44608
int sum = 'A' + 10; // 유추: (1) 산술적인 연산 결과로는 75
// (2) 문자로써 연산 결과로는 'K'
System.out.println("sum: " + sum); // 75
System.out.println("sum: " + (char)sum); // K
System.out.println("A가 a보다 큽니까?: " + ('A' > 'a')); // false, 아스키코드표 기준 A = 65, a = 97
//문자끼리 숫자만 가능한 연산도 가능하다!
// 특이 케이스 5. byte끼리의 연산, short끼리의 연산
byte b1 = 1;
byte b2 = 10;
// byte result = b1 + b2;
// Type mismatch: cannot convert from int to byte: 자료형이 맞지 않아! int를 byte로 바꿀 수 없어
byte result = (byte)(b1 + b2); // 정수형의 기본형은 int이기 때문에 나타나는 오류이므로 결과값 int를 byte로 변환
// byte나 short로 연산 시 무조건 연산 결과를 int로 취급됨
// => 강제로 형변환을 하면 저장 가능
}
강제 형변환(명시적 형변환): 큰 크기의 자료형을 작은 크기의 자료형으로 형변환 할 경우
public void forceCasting() {
// 1. double (8byte) -> float (4byte)
//float f1 = 4.0;
float f1 = 4.0f; // 실수형은 기본 double형으로 간주하므로 반드시 f를 붙여 줘야 함!
// float f1 = (float)4.0; // 혹은 이렇게
double d2 = 8.0;
// float f2 = d2;
float f2 = (float)d2;
// 2. double (8byte) -> int (4byte)
double d3 = 10.89;
int i3 = (int)d3; // 10.89 -> 10
System.out.println("i3: " + i3);
// 10 소수점 아래 내용이 절삭됨(즉, 소수점 아래 데이터가 손실되므로 신중히 진행해야 함)
int iNum = 10;
double dNum = 5.89;
// int iSum = iNum + dNum;
// int가 4byte, double이 8byte이므로 int가 double로 자동 형변환(오른쪽 값)되지만 int 상자(왼쪽 공간)에 담고 싶어서 오류가 뜨는 것!
// iNum이 double 형으로 자동 형변환되고(10 -> 10.0)
// iNum과 dNum이 더해지면서 15.89가 됨
// => double 형태 결과인 15.89 값이 int형 상자인 iSum에 담기려고 해서 오류
// 해결 방법 1. 연산결과를 int형에 맞춰서 강제 형변환
int iSum = (int)(iNum + dNum);
System.out.println("iSum: " + iSum); // 15
// 해결 방법 2. 덧셈 연산 전에 dNum을 int형으로 강제 형변환 후에 덧셈 진행
int iSum2 = iNum + (int)dNum;
System.out.println("iSum2: " + iSum2); // 15
// 해결 방법 1과 해결 방법 2의 순서 차이
// 해결 방법 1
// 1단계: iNum이 double로 자동형변환
// 2단계: 바뀐 iNum과 dNum이 더해지고
// 3단계: 더해진 결과가 int형으로 강제형변환
// 해결 방법 2
// 1단계: dNum이 int로 강제형변환
// 2단계: iNum과 dNum이 더해짐
// 해결 방법 3. 애초에 결과값을 담을 변수를 double형으로 지정
double dSum = iNum + dNum; // iSum은 자동형변환으로 double로 형변환 되며, 데이터 손실 없이 정확한 값이 담김
System.out.println("dSum: " + dSum);
}
/*
* (바꾸고자하는자료형)값;
*
* 작은사이즈 -> 큰사이즈
* 큰사이즈 -> 작은사이즈
*
*/
<print 출력문>
출력문의 종류
System.out.println(출력하고자하는값); => 값 출력 후에 줄바꿈(개행) 넣어 줌
System.out.print(출력하고자하는값); => 값 출력만 해 줌
=> 문자열이 아니더라도 출력 가능함
System.out.printf("출력하고자하는형식(정수/실수/문자/문자열)", 출력하고자하는값);
=> f는 format (형식)을 의미
=> 형식에 맞춰서 값들이 들어가서 출력되는 형식, 줄바꿈은 일어나지 않음
=> 즉, 문자열 안에 그 값이 들어갈 자리를 다음과 같이 형식으로 잡아 줘야 함
형식
%d: 정수가 들어갈 수 있는 형식 // d는 10진수(decimal)
%f: 실수가 들어갈 수 있는 형식
%c: 문자가 들어갈 수 있는 형식
%s: 문자열이 들어갈 수 있는 형식
package com.kh.variable;
// printf 구문에 대해서 공부
public class D_Printf {
public void printTest() {
// 정수 테스트
int iNum1 = 10;
int iNum2 = 20;
// iNum1: xx, iNum2: xx 형식으로 출력해 보자
// 1. println 사용
System.out.println("iNum1: " + iNum1 + ", iNum2: " + iNum2);
// 2. printf 사용 => 정수값이므로 %d 형식으로 자리를 잡아 줌
// 줄바꿈 기능이 없으므로 줄바꿈이 일어날 수 있도록 유도
System.out.printf("iNum1: %d, iNum2: %d \n", iNum1, iNum2);
// 주의할 점: 구멍의 종류와 개수를 맞춰서 나열해 줘야 함!
// 10 + 20 = 30을 출력해 보자
// 1. println 사용
System.out.println(iNum1 + " + " + iNum2 + " = " + (iNum1 + iNum2));
// 2. printf 사용
System.out.printf("%d + %d = %d \n", iNum1, iNum2, iNum1 + iNum2);
// 정수 형식과 같이 쓸 수 있는 옵션
System.out.printf("%5d \n", iNum1); // %5d: 5칸의 공간 중 오른쪽 정렬
System.out.printf("%-5d \n", iNum1); // %-5d: 5칸의 공간 중 왼쪽 정렬
// 실수 테스트
double dNum = 4.27546789;
// dNum: xx.xxx 형식으로 출력
System.out.println("dNum: " + dNum); // 4.27546789
System.out.printf("dNum: %f \n", dNum); // 4.275468 소수점 7번째 자리에서 반올림
// %f: 소수점 아래 7번째 자리에서 반올림되어 소수점 아래 6번째 자리까지만 출력됨
// 실수 형식과 같이 쓸 수 있는 옵션
System.out.printf("dNum: %.1f \n", dNum); // 4.3
// %.1f: 소수점 아래 2번째 자리에서 반올림되어 소수점 아래 1번째 자리까지만 출력됨
// 문자와 문자열 테스트
char ch = 'a';
String str = "Hello";
System.out.printf("%c %s \n", ch, str); // a Hello
// 문자 또는 문자열과 같이 쓸 수 있는 옵션
System.out.printf("%C %S \n", ch, str); // A HELLO, 모두 대문자로 출력
// %C, %S: 영어 알파벳일 경우 대문자로 변경해서 출력
}
}