콘텐츠로 이동

자바 기본 프로그래밍

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”, “한글”, “계속하세요”
        String toolName="JDK";
      
    • 문자열이섞인+연산->문자열연결
        toolName + 1.8 // "JDK1.8"
        "(" + 3 + "," + 5 + ")" 
        // "(3,5)" System.out.println(toolName + "이 출시됨");
        // "JDK1.8이 출시됨" 출력
      

5) 변수와 선언

프로그램 실행 중에 값을 임시 저장하기 위한 공간

  • 변수값은 프로그램 수행중 변경될 수 있음
int radius;
double weight = 75.56; 
char c1 , c2, c3 = 'c';

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 타입으로 컴파일

      double d = 0.1234;
      double e = 1234E-4; // 1234E-4 = 1234 x 10^-4 이므로 0.1234와 동일
    

  • 숫자 뒤에 f(float)나 d(double)을 명시적으로 붙이기도 함

      float f = 0.1234f;
      double w = .1234D; // .1234D와 .1234는 동일
    

8) 문자 리터럴

  • 단일 인용부호(' ')로 문자 표현

    • 'a', 'W', '가', '*', '3', '7'
        char a = 'W';
        char b = '글';
        char c = \uae00; // '글'의 유니코드 값(ae00) 사용
      
    • \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 타입 변수에 치환하거나 조건문에 이용

      boolean a = true;
      boolean b = 10 > 0; // 10>0가 참이므로 b 값은 true 
      boolean c = 1;      // 타입 불일치 오류.
                          //C/C++와 달리 자바에서 1,0을 참, 거짓으로 사용 불가 
      while(true) {       // 무한 루프      
      ... 
      }
    

  • null 리터럴

    • 레퍼런스에 대입 사용
          int n = null; // 기본 타입에 사용 불가 String str = null;
          String str = Good";
      

10) 상수

  • 상수 선언
    • final 키워드 사용
    • 선언 시 초기값 지정
    • 실행 중 값 변경 불가
        final double PI = 3.141592;
      
        final int LENGTH = 20;
        static final double PI = 3.141592;
        // static으로 선언하는 것이 바람직(5장 참조)
      

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) 타입 변환과 자동 타입 변화

타입변화 - 한타입의 값을 다른 타입의 값으로 변화

자동 타입 변환 - 컴파일러에 의해 원래의 타입보다 큰 타입으로 자동 변환 - 치환문(=)이나 수식 내에서 타입이 일치하지 않을 때

  long m = 25; // 25는 int 타입 25가 long 타입으로 자동 변환
  double d = 3.14 * 10; // 실수 연산 위해 10이 10.0으로 자동 변환

13) 강제 타입 변환

  • 개발자의 의도적 타입 변환
  • () 안에 개발자가 명시적으로 타입 변환 지정

      int n = 300;
      byte b = n ; // int 타입이 byte로 자동 변환 안 됨
      byte b= (byte)n;
    
    - 강제 변환은 값 손실 우려

      byte b = (byte)n; //손실 발생
    
      double d = 1.9; 
      intn=(int)d; //n=1 
      //강제타입변환으로 소수점 이하 0.9 손실
    

2. Scanner객체와 연산자

1) System.in

  • 키보드와 연결된 자바의 표준 입력 스트림
  • 입력되는 키를 바이트(문자 아님)로 리턴하는 저수준 스트림
  • System.in을 직접 사용하면 바이트를 문자나 숫자로 변환하는 많은 어려움 있음

2) Scanner와 Scanner 객체 생성

Scanner 클래스

‐ 읽은 바이트를 문자, 정수, 실수, 불린, 문자열등 다양한 타입으로 변환하여 리턴 ‐ java.util.Scanner

객체 생성

  import java.util.Scanner; // 임포트 문 필요
  ...
  Scanner a = new Scanner(System.in); // 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의 자리 분리
        69 / 10 = 6   // 몫 6
        69 % 10 = 9   // 나머지 9
      
    • x가 홀수인지 판단
        int r = n % 2; // r이 1이면 n은 홀수, 0이면 짝수
      
    • n의값이3의배수인지확인
        int s = n % 3; // s가 0이면 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을 조건연산자로 간결하게 표현 가능
  int x = 5;
  int y = 3;

  int big;
  if (x > y)
    big = x;
  else 
    big = y;   // -> int big = (x > y) ? x:y;
  int a = 3, b = 5;
  (a > b) ? (a - b) : (b - a)

2) 단순 if 문, if-else 문

  • 단순 if 문 : 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 실행
  if(조건식) {
    ... 실행문장 1...  // 조건식이 참인 경우
  } else {
    ... 실행문자 2...  // 조건식이 거짓인 경우
  }
  if(score >= 90) 
    System.out.println("합격입니다.");
  else 
    System.out.println("불합격입니다.");
  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; 
  }
  switch(a) {
    case a : // 오류. 변수 사용 안됨 
    case a > 3 : // 오류. 수식 안됨 
    casea==1: //오류.수식안됨
  }
예제
  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
봄입니다.