자바 기본 프로그래밍
1. 자바 프로그램의 구조와 데이터 타입
1) Hello, 자바 프로그램의 기본 구조 [예제 2-1]
/*
* 소스 파일 : Hello.java
*/
public class Hello { //클래스
public static int sum(int n, int m) {
return n + m;
}
// main() 메소드에서 실행 시작
public static void main(String[] args) {
int i = 20;
int s;
char a;
s = sum(i, 10); // sum() 메소드 호출
a = '?';
System.out.println(a); // 문자 '?' 화면 출력
System.out.println("Hello"); // "Hello" 문자열 화면 출력
System.out.println(s); // 정수 s 값 화면 출력
}
}
?
Hello
30
2) 식별자 (identifier)
클래스, 변수, 상수, 메소드 등에 붙이는 이름
식별자의 원칙
- ‘@’, ‘#’, ‘!’ 와 같은 특수문자, 공백 또는 탭은 식별자로 사용할 수 없으나 ‘_’, ‘$’는 사용 가능
- 유니코드 문자 사용가능. 한글사용가능
- 자바 언어의 키워드는 식별자로 사용불가
- 식별자의 첫 번째 문자로 숫자는 사용불가
- ‘_’또는‘$’를 식별자 첫번째 문자로 사용할 수 있으나 일반적으로 잘 사용하지 않는다.
- 불린 리터럴 (true, false)과 널 리터럴(null)은 식별자로 사용불가
- 길이제한없음
대소문자 구별 ‐ int barChart; 와 int barchart;는 서로 다른 식별자 선언
3) 자바의 데이터 타입
기본타입 (8개)
타입 | 자료형 | 크기 | 범위 |
---|---|---|---|
논리타입 | boolean | 1바이트 | true 또는 false |
문자타입 | char | 2바이트 | Unicode |
정수타입 | byte | 1바이트 | -128 ~ 127 |
short | 2바이트 | -32768 ~ 32767 | |
int | 4바이트 | \(-2^{31}\) ~ \(2^{31} - 1\) | |
long | 8바이트 | \(-2^{63}\) ~ \(2^{63} - 1\) | |
실수타입 | float | 4바이트 | -3.4E38 ~ 3.4E38 |
double | 8바이트 | -1.7E308 ~ 1.7E308 |
레퍼런스 타입 : 1개이며 용도는 다음 3가지(레퍼런스는 C/C++의 포인터와 유사한 개념 그러나 메모리 주소는 아님)
- 클래스(class)에 대한 레퍼런스
- 인터페이스(interface)에 대한 레퍼런스
- 배열(array)에 대한 레퍼런스
4) 문자열
- 문자열은 기본 타입이 아님
- String 클래스로 문자열 표현
- 문자열 리터럴 – “JDK”, “한글”, “계속하세요”
- 문자열이섞인+연산->문자열연결
5) 변수와 선언
프로그램 실행 중에 값을 임시 저장하기 위한 공간
- 변수값은 프로그램 수행중 변경될 수 있음
6) 리터럴과 정수 리터럴
리터럴(literal)
- 프로그램에서 직접 표현한 값
- 정수, 실수, 문자, 논리, 문자열 리터럴 있음
정수 리터럴 - 10진수, 8진수, 16진수, 2진수 리터럴
graph LR
A["15 -> 10진수 리터럴 15<hr>015 -> 0으로 시작하면 8진수 십진수로 13<hr>0x15 -> 0x로 시작하면 16진수. 십진수로 21 <hr>0b0101 -> 0b로 시작하면 2진수. 십진수로 5"] --> B["int n = 15;<hr>int m = 015;<hr>int k = 0x15;<hr>int b = 0b0101;"];
- 정수 리터럴은 int 형으로 컴파일
- long타입 리터럴은 숫자뒤에 L 또는 l을 붙여 표시 ex) long g = 24L;
7) 실수 리터럴
소수점 형태나 지수 형태로 표현한 실수
-
실수 타입 리터럴은 double 타입으로 컴파일
-
숫자 뒤에 f(float)나 d(double)을 명시적으로 붙이기도 함
8) 문자 리터럴
-
단일 인용부호(' ')로 문자 표현
- 'a', 'W', '가', '*', '3', '7'
- \u다음에 4자리 16진수로, 2 바이트의 유니코드(Unicode)
-
특수문자 리터럴은 백슬래시()로 시작
특수문자 리터럴 의미 특수문자 리터럴 의미 '\b' 백스페이스(backspace) '\r' 캐리지 리턴(carriage return) '\t' 탭(tab) '\"' 이중 인용부호(double quote) '\n' 라인피트(line feed) '\'' 단일 인용부호(single quote) '\f' 폼피드(form feed) '\' 백슬래시(backslash)
9 논리 타입 리터럴 이외 리터럴
-
boolean 타입 변수에 치환하거나 조건문에 이용
-
null 리터럴
- 레퍼런스에 대입 사용
10) 상수
- 상수 선언
final
키워드 사용- 선언 시 초기값 지정
- 실행 중 값 변경 불가
11) 리터럴, 상수 사용하기
원의 면적을 구하는 프로그램을 작성하라.
public class CircleArea {
public static void main(String[] args) {
final double PI = 3.14; // 원주율을 상수로 선언
double radius = 10.2; // 원의 반지름
double circleArea = radius*radius*PI; // 원의 면적 계산
// 원의 면적을 화면에 출력한다.
System.out.print("반지름 " + radius + ", ");
System.out.println("원의 면적 = " + circleArea); } }
반지름 10.2, 원의 면적 = 326.68559999999997
12) 타입 변환과 자동 타입 변화
타입변화 - 한타입의 값을 다른 타입의 값으로 변화
자동 타입 변환 - 컴파일러에 의해 원래의 타입보다 큰 타입으로 자동 변환 - 치환문(=)이나 수식 내에서 타입이 일치하지 않을 때
13) 강제 타입 변환
- 개발자의 의도적 타입 변환
-
() 안에 개발자가 명시적으로 타입 변환 지정
- 강제 변환은 값 손실 우려
2. Scanner객체와 연산자
1) System.in
- 키보드와 연결된 자바의 표준 입력 스트림
- 입력되는 키를 바이트(문자 아님)로 리턴하는 저수준 스트림
- System.in을 직접 사용하면 바이트를 문자나 숫자로 변환하는 많은 어려움 있음
2) Scanner와 Scanner 객체 생성
Scanner 클래스
‐ 읽은 바이트를 문자, 정수, 실수, 불린, 문자열등 다양한 타입으로 변환하여 리턴 ‐ java.util.Scanner
객체 생성
- 키보드에 연결된 System.in에게 키를 읽게 하고, 원하는 타입으로 변환하여 리턴
3) Scanner를 이용한 키 입력
Scanner에서 키 입력 받기
- Scanner는 입력되는 키 값을 공백으로 구분되는 토큰 단위로 읽음
- 공백 문자: ‘\t’, ‘\f’, ‘\r’, ‘ ’, ‘\n’
개발자가 원하는 타입 값으로 쉽게 읽을 수 있음
Scanner scanner = new Scanner(System.in);
String name = scanner.next(); // "Kim"
String city = scanner.next(); // "Seoul"
int age = scanner.nextInt(); // 20
double weight = scanner.nextDouble(); // 65.1
boolean single = scanner.nextBoolean(); // true
4) Scanner 주요 메소드
메소드 | 설명 |
---|---|
String next() | 다음 토큰을 문자열로 리턴 |
byte nextByte() | 다음 토큰을 byte 타입으로 리턴 |
short nextShort() | 다음 토큰을 short 타입으로 리턴 |
int nextInt() | 다음 토큰을 int 타입으로 리턴 |
long nextLong() | 다음 토큰을 long 타입으로 리턴 |
float nextFloat() | 다음 토큰을 float 타입으로 리턴 |
double nextDouble() | 다음 토큰을 double 타입으로 리턴 |
String nextLine() | '\n' 을 포함하는 한 라인을 읽고 '\n' 을 버린 나머지만 리턴 |
void close() | Scanner의 사용 종료 |
boolean hasNext() | 현재 입력된 토큰이 있으면 true , 아니면 새로운 입력이 들어올 때까지 무한정 기다려서, 새로운 입력이 들어오면 그 때 true 리턴, crtl -z 키가 입력되면 입력 끝이므로 false 를 리턴 |
5) Scanner를 이용한 키 입력 연습
import java.util.Scanner;
public class ScannerEx {
public static void main(String args[]) {
System.out.println("이름, 도시, 나이, 체중, 독신 여부를 빈칸으로 분리하여 입력하세요");
Scanner scanner = new Scanner(System.in);
String name = scanner.next();
System.out.println("당신의 이름은 " + name + "입니다.");
String city = scanner.next();
System.out.println("당신이 사는 도시는 " + city + "입니다.");
int age = scanner.nextInt();
System.out.println("당신의 나이는 " + age + "살입니다.");
double weight = scanner.nextDouble(); // 실수 토큰 읽기
System.out.println("당신의 체중은 " + weight + "kg입니다.");
boolean single = scanner.nextBoolean();
System.out.println("당신은 독신 여부는 " + single + "입니다.");
scanner.close();
}
}
이름, 도시, 나이, 체중, 독신 여부를 빈칸으로 분리하여 입력하세요.
Kim Seoul 20 65.1 true
당신의 이름은 Kim입니다. 당신이 사는 도시는 Seoul입니다.
당신의 나이는 20살입니다. 당신의 체중은 65.1kg입니다.
당신은 독신 여부는 true입니다.
6) 연산자
주어진 식을 계산하여 결과를 얻어내는 과정
연산의 종류 | 연산자 |
---|---|
증감 | ++ -- |
산술 | + - * / % |
시프트 | >> << >>> |
비교 | > < >= <= == != |
비트 | & |
논리 | && |
조건 | ? : |
대입 | = *= /= += -= &= ^= |
7) 산술 연산자
- 더하기(+), 빼기(-), 곱하기(*), 나누기(/), 나머지(%)
- /와 % 응용
- 10의 자리와 1의 자리 분리
- x가 홀수인지 판단
- n의값이3의배수인지확인
8) /와 % 산술 연산자 응용
import java.util.Scanner;
public class ArithmeticOperator {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("정수를 입력하세요:");
int time = scanner.nextInt(); // 정수 입력
int second = time % 60; // 60으로 나눈 나머지는 초
int minute = (time / 60) % 60; // 60으로 나눈 몫을 다시 60으로 나눈 나머지는 분
int hour = (time / 60) / 60; //60으로 나눈 몫을 다시 60으로 나눈 몫은 시간
System.out.print(time + "초는 ");
System.out.print(hour + "시간, ");
System.out.print(minute + "분, ");
System.out.println(second + "초입니다.");
scanner.close();
}
}
정수를 입력하세요:4000 4000초는 1시간, 6분, 40초입니다
9) 비트 연산자
피 연산자의 각 비트들을 대상으로 하는 연산
비트 연산자 | 내용 |
---|---|
a & b | a와 b의 각 비트들의 AND 연산, 두 비트 모두 1일 때만 1이 되며 나머지는 0이 된다. |
a | b | a와 b의 각 비트들의 OR 연산, 두 비트 모두 0일 때만 0이 되며 나머지는 1이 된다. |
a ^ b | a와 b의 각 비트들의 XOR 연산, 두 비트가 서로 다르면 1. 같으면 0이다. |
~ a | 단항 연산자로서 a의 각 비트들에 NOT 연산. 1을 0으로, 0을 1로 변환한다. |
10) 시프트 연산자
시프트 연산자 | 나용 |
---|---|
a >> b | a의 각 비트를 오른쪽으로 b번 시프트한다. 최상의 비트의 빈자리는 시프트 전의 최상위 비트로 다시 채운다. 산술적 오른쪽 시프트라고 한다. |
a >>> b | a 의 각 비트를 오른쪽으로 b번 시프트한다. 그리고 최상위 비트의 빈자리는 0으로 채운다. 논리적 오른쪽 시프트라고 한다. |
a << b | a의 각 비트를 왼쪽을 b번 시프트한다. 그리고 최하위 비튼의 빈자리는 0으로 채운다. 산술적 왼쪽 시프트라고 한다. |
11) 비교 연산자, 논리 연산자
- 비교연산자 : 두 개의 값을 비교하여 true/false 결과
- 논리연산자 : 두 개의 논리 값에 논리 연산. 논리 결과
비교 연산자 | 내용 | 논리 연산자 | 내용 |
---|---|---|---|
a < b | a가 b보다 작으면 true | !a | a가 true 이면 false, false이면 true |
a > b | a가 b보다 크면 true | a^b | a와 b의 XOR 연산, a, b가 같으면 false |
a <= b | a가 b보다 작거나 같으면 true | a || b | a와 b의 OR 연산, a와 b 모두 false인 경우만 false |
a >= b | a가 b보다 크거나 같으면 true | a && b | a와 b의 AND 연산, a와 b 모두 true인 경우만 true |
a == b | a가 b와 같으면 true | ||
a != b | a가 b와 같지 않으면 true |
(age >= 20) && (age < 30) // 나이(int age)가 20대인 경우
(c >= 'A') && (c <= 'Z') // 문자(char c)가 대문자인 경우
(x>=0) && (y>=0) && (x<=50) && (y<=50) // (x,y)가 (0,0)과 (50,50)의 사각형 내에 있음
12) 대입 연산자, 증감 연산자
대입 연산자 | 내용 | 대입연산자 | 내용 |
---|---|---|---|
a = b | b의 값을 a에 대입 | a &= b | a = a & b와 동일 |
a += b | a = a + b와 동일 | a ^= b | a = a ^ b와 동일 |
a -= b | a = a - b와 동일 | a | b | a = a | b와 동일 |
a *= b | a = a * b와 동일 | a <<= b | a = a << b와 동일 |
a /= b | a = a / b와 동일 | a >>= b | a = a >> b와 동일 |
a %= b | a = a % b와 동일 | a >>>= b | a = a >>> b와 동일 |
증감 연산자 | 내용 | 증감 연산자 | 내용 |
---|---|---|---|
a++ | a를 먼저 사용한 후에 1증가 | ++a | a를 먼저 1증가한 후에 사용 |
a-- | a를 먼저 사용한 후에 1감소 | --a | a를 먼저 1감소한 후에 사용 |
public class AssignmentIncDecOperator {
public static void main(String[] args) {
int a=3, b=3, c=3;
// 대입 연산자 사례
a += 3; // a=a+3 = 6
b *= 3; // b=b*3 = 9
c %= 2; //c=c%2=1
System.out.println("a=" + a + ", b=" + b + ", c=" + c);
int d = 3;
// 증감 연산자 사례
a = d++; // a=3, d=4
System.out.println("a=" + a + ", d=" + d);
a = ++d; // d=5, a=5
System.out.println("a=" + a + ", d=" + d);
a = d--; // a=5, d=4
System.out.println("a=" + a + ", d=" + d);
a = --d; // d=3, a=3
System.out.println("a=" + a + ", d=" + d);
}
}
// a=6, b=9, c=1 a=3, d=4 a=5, d=5 a=5, d=4 a=3, d=3
3 조건문
1) 조건 연산자 ?:
- opr1 ? opr2 : opr3
- 3 개의 피연산자로 구성된 삼항(ternary) 연산자
- if-else을 조건연산자로 간결하게 표현 가능
2) 단순 if 문, if-else 문
- 단순 if 문 : if의 괄호 안에 조건식(논리형 변수나 논리 연산)
- 실행문장이 단일 문장인 경우 둘러싸는 {, } 생략 가능
if(n%2 == 0) {
System.out.print(n);
System.out.println("은 짝수입니다.");
}
if(score >= 80 && score <= 89)
System.out.println("학점은 B입니다.");
- if-else 문 : 조건식이 true면 실행문장1, false이면 실행문장2 실행
import java.util.Scanner;
public class Twenties {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("나이를 입력하시오:");
int age = scanner.nextInt();
if((age>=20) && (age<30)) { // age가 20~29 사이인지 검사
System.out.print("20대입니다. ");
System.out.println("20대라서 행복합니다!");
} else
System.out.println("20대가 아닙니다.");
scanner.close();
}
}
나이를 입력하시오: 23 20대입니다. 20대라서 행복합니다!
3) 다중 if-else 문
if (조건식 1) {
실행문자 1; // 조건식 1이 참인 경우
}
else if(조건식 2) {
실행문장 2; // 조건식 2가 참인 경우
}
else if (조건식 m) {
............ // 조건식 m이 참인 경우
}
else {
실행문장 n; // 앞의 모든 조건이 거짓인 경우
}
if(score >= 90) { // score가 90 이상
grade = 'A';
} else if(score >= 80) { // 80 이상 90 미만
grade = 'B';
} else if(score >= 70) { // 70 이상 80 미만
grade = 'C';
} else if(score >= 60) { // 60 이상 70 미만
grade = 'D';
} else { // 60 미만
grade = 'F';
}
import java.util.Scanner;
public class NestedIf {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("점수를 입력하세요(0~100):");
int score = scanner.nextInt();
System.out.print("학년을 입력하세요(1~4):");
int year = scanner.nextInt();
if(score >= 60) { // 60점 이상
if(year != 4)
System.out.println("합격!"); // 4학년 아니면 합격
else if(score >= 70)
System.out.println("합격!"); // 4학년이 70점 이상이면 합격
else
System.out.println("불합격!"); // 4학년이 70점 미만이면 불합격
}
else // 60점 미만 불합격 System.out.println("불합격!");
scanner.close();
}
}
점수를 입력하세요(0~100): 65 학년을 입력하세요(1~4): 4 불합격!
4) switch문
case의 비교 값과 일치하면 해당 case의 실행문장 수행
- break를 만나면 switch문을 벗어남
case의 비교 값과 일치하는 것이 없으면 default 문 실행
- default문은 생략 가능
switch(식) {
case 값1: // 식의 결과가 값1과 같을 때
실행문장 1;
break;
case 값2: // 식의 결과가 값2과 같을 때
실행문장 2:
break;
...
case 값m:
실행 문장 m; // 식의 결과가 값m과 같을 때
break;
default: // 어느 것과도 같지 않을때
실행문장 n;
}
char grade='B';
switch(grade) {
case 'A':
System.out.println("축하합니다.");
System.out.println("잘했습니다.");
break;
case 'B':
System.out.println("좋아요.");
break;
case 'C':
System.out.println("노력하세요.");
break;
default:
System.out.println("탈락입니다!");
}
case 문의 값
- 문자, 정수, 문자열 리터럴(JDK 1.7부터)만 허용
- 실수 리터럴은 허용되지 않음
int b;
switch(c%2) {
case 1 : ...; break;
case 2 : ...; break; //정수 리터럴
}
char c; switch(c) {
case '+' : ...; break;
case '-' : ...; break; //문자 리터럴
}
String s = "예";
switch(s) {
case "예" : ...; break; //문자열 리터럴
case "아니요" : ...; break;
}
import java.util.Scanner;
public class Season {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("월(1~12)을 입력하시오:");
int month = scanner.nextInt(); // 정수로 월 입력
switch(month) {
case 3:
case 4:
case 5:
System.out.println("봄입니다.");
break;
case 6: case 7: case 8:
System.out.println("여름입니다.");
break;
case 9: case 10: case 11:
System.out.println("가을입니다.");
break;
case 12: case 1: case 2:
System.out.println("겨울입니다."); break;
default:
System.out.println("잘못된 입력입니다.");
}
scanner.close();
}
}
월(1~12)을 입력하시오: 3
봄입니다.