▼ 제어문은 예제 위주로 정리하려 한다..

 

----------------------------------------------------------------------------------------------------------------------

 

[제어문의 종류]

- 제어문이란? Control Statement, 프로그램의 흐름(fow)을 바꾸어주는 명령문

제어문 코드 내용
조건문

if, if-else 제한을 두거나 범위를 지정하여 선택
switch-case 다차원 선택 (조건식에 따라 여러개의 결과값으로 이동, 명령 수행)
반복문
(Loop)
for 반복 횟수를 알 때 주로 사용
while 반복 횟수를 모를 때 (화일 처리/키보드입력)
do while 반복 횟수를 모르고, 특정 명령 수행 후 지속여부 확인 후 반복 시 사용
기타 break switch-case 또는 반복문에서 종료 역할. //제어문 밖으로 
continue 반복문에서만 사용 가능 //반복문의 끝으로 이동
return  

* 객체지향에서 다루는 제어자(motifier)와는 다르다.

* printf의 제어문자 \n, \r... 는 다른 말로 이스케이프라고 하고, 위 제어문과 다르다.

  (프로그래밍 문법을 번역할 때 '제어'를 붙이는 경우가 참 많은 것 같은데... ;; 그럴 땐 원어를 보면 될 것 같다.)

 

1. 조건문 - if, switch

 조건문은 말 그대로 알고리즘 내에 [조건]을 걸어 선택을 할 때 사용
 - if문, if-else
 - switch : 다차원 선택

 

1) If문

 

(1) if문 예제_명령프롬프트에서 받은 숫자 확인

package practice;

public class PromptTest {

	public static void main(String[] args) {
		String input = args[0];
		int num = Integer.parseInt(input);
		
		if(num == 0) {
			System.out.println("입력한 숫자는 0입니다.");
		}
		
		if(num != 0) {
			System.out.println("입력한 숫자는 0이 아닙니다.");
		}
		
	}

}

>> 결과 (argument : 3)

입력한 숫자는 0이 아닙니다.

 

(2) if - else문

- 자바는 자바스크립트와 달리 else if문이 없다.

- if - else문 안에 중첩된 if-else문이 마치 else if문처럼 보이는 것.. 

package mymain;

import java.util.Scanner;

public class _02_Ex_if4 {

	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		
		int kor; //나의 국어점수
		String grade = "F"; //결과(나의 등급)
		System.out.print("국어 : ");
		kor = scanner.nextInt();
		
		//등급 세분
		
		if(kor>=0 && kor<=100) 
		{
			if(kor>=96) grade = "A+";
			else if(kor>=93) grade = "A";
			else if(kor>=90) grade = "A0";
			else if(kor>=86) grade = "B+";
			else if(kor>=83) grade = "B";
			else if(kor>=80) grade = "B0";
			else if(kor>=76) grade = "C+";
			else if(kor>=73) grade = "C";
			else if(kor>=70) grade = "C0";
			else if(kor>=66) grade = "D+";
			else if(kor>=63) grade = "D";
			else if(kor>=60) grade = "D0";
			else if(kor>=56) grade = "F+";
			else if(kor>=53) grade = "F";
			else if(kor>=50) grade = "F0";
		}
		else
		{
			System.out.printf("입력된 점수 [%d]는 유효하지 않습니다.",kor);
		}
		
		System.out.printf("국어점수 : %d(점) --> 등급 : %s\n",kor,grade);
		
		scanner.close();
	}

}

 

▼ 위 코드는 사실상

    1) if(kor >= 96) else 가 있을 때

                       2) else안에 : if(kor>=93), if(kor>=90)......이 들어있는 것과 같음.

 

(3) 중첩 if문에서 코드를 간결히 하기 _ 위의 원리를 알면 아래와 같이 &&로 일일히 범위 지정을 하지 않을 수 있다.

package mymain;

import java.util.Scanner;

public class _02_Ex_if3 {

	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		
		int kor; //나의 국어점수
		//String grade="ABCDF"; //등급
		char result = 'F'; //결과(나의 등급)
		System.out.print("국어 : ");
		kor = scanner.nextInt();
		
		//효율적 코드 
		//방법 1)
		/*
		if(kor>=90 && kor <= 100) 
			result = grade.charAt(0);
		else if(kor>=80 && kor <90) 
			result = grade.charAt(1);
		else if(kor>=70 && kor <80) 
			result = grade.charAt(2);
		else if(kor>=60 && kor <70) 
			result = grade.charAt(3);	
		*/
		//방법 2)
		//유효범위를 먼저 체크(0~100)
		if(kor>=0 && kor<=100) 
		{
			if(kor>=90) result = 'A';
			else if(kor>=80) result = 'B';
			else if(kor>=70) result = 'C';
			else if(kor>=60) result = 'D';
			//else grade = 'F';
		}
		else
		{
			System.out.printf("입력된 점수 [%d]는 유효하지 않습니다.",kor);
		}
		
		System.out.printf("국어점수 : %d(점) --> 등급 : %c\n",kor,result);
		
		scanner.close();
	}

}

 

2) switch문

 - 다차원 선택
 - break를 걸지 않으면 내 case의 명령 이후에, 다음 case의 명령, 그 다음 case의 명령.... 수행

- 로그인한 사용자의 등급을 체크하여 권한을 부여하는 코드

//break를 안 쓰면 grantDelete()부터 아래까지 명령 하나씩 실행
//level 2면, grantWrite(), grantRead() 실행

switch(level){
	case 3 : grantDelete();
    case 2 : grantWrite();
    case 1 : grantRead();
}

- 계절 예제

package mymain;

import java.util.Scanner;

public class _04_Ex_switch2_계절구하기 {
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		
		int month;
		String season = "";
		
		System.out.print("월 : ");
		month = scanner.nextInt();
		
		//유효성 검사
		if(month >= 1 && month <= 12) {
			//계절 구하기__방법1
			switch(month) 
			{
				case 3: case 4:  case 5: season="봄";     break;
				case 6: case 7:  case 8: season="여름";   break;
				case 9: case 10: case 11: season= "가을"; break;
				default : season="겨울";
			}
		}else {
			System.out.println("월은 1~12사이 값을 입력하세요.");
		}
		
		System.out.printf("[%d월]의 계절은 [%s]입니다.",month,season);
		
		scanner.close();
	}

}

 

- 학점 내기 예제_ switch의 조건식에서 연산자 /를 통해 몫을 구함

package mymain;

import java.util.Scanner;

public class _05_Ex_switch3_문제 {

	public static void main(String[] args) {
		//1.국어점수 입력받는다.
		//2. switch문을 이용해서 등급을 산출하세요.(ABCDF)--수식활용(10배)
		
		Scanner scanner = new Scanner(System.in);
		
		System.out.print("국어 점수 : ");
		int score = scanner.nextInt();
		char grade = 'F';
		
		//유효성 확인
		if(score>=0 && score<=100) {
			//등급내기
			switch(score/10) 
			{
				case 10 : 
				case  9 : grade = 'A'; break;
				case  8 : grade = 'B'; break;
				case  7 : grade = 'C'; break;
				case  6 : grade = 'D'; break;
				default : grade = 'F';
			}
			
			System.out.printf("[%d]점일 때, 등급은 [%c]입니다.",score,grade);
			
		}else {
			System.out.println("유효하지 않은 값입니다.(0~100사이)");
		}
		
		scanner.close();
	}

}

 

- 가위바위보 예제

package practice;

import java.util.Scanner;

public class SwitchTest {

	public static void main(String[] args) {
		//가위(1) 바위(2) 보(3)
		
		String[] optArr = {"","가위","바위","보"};
		
		Scanner scanner = new Scanner(System.in);
		System.out.print("가위(1), 바위(2), 보(3) 중 하나 선택 : ");
		int user_num = scanner.nextInt();
		
		int comp_num = (int)(Math.random()*3)+1;
		
		if(user_num==1 || user_num==2 || user_num ==3) {
			switch(user_num - comp_num) {
				case -2 : case 1 : 
					System.out.printf("당신 : [%s] vs 컴퓨터 : [%s] = 당신의 승!\n", optArr[user_num], optArr[comp_num]);
					break;
				case -1 : case 2 :
					System.out.printf("당신 : [%s] vs 컴퓨터 : [%s] = 비겼네요.\n", optArr[user_num], optArr[comp_num]);
					break;
				default :
					System.out.printf("당신 : [%s] vs 컴퓨터 : [%s] = 졌네요.ㅠㅠ\n", optArr[user_num], optArr[comp_num]);
			}
		}else {
			System.out.println("잘못 입력했습니다.");
		}
		
		scanner.close();
	}

}

>> 결과

가위(1), 바위(2), 보(3) 중 하나 선택 : 3
당신 : [보] vs 컴퓨터 : [가위] = 졌네요.ㅠㅠ

 

2. for/while/do-while

 - for    문 : 반복횟수를 알 때
 - while 문 : 반복횟수를 모를 때(화일처리/키보드입력)
      pf. 파일 처리의 경우
      --> 사용자가 file을 선택하여 읽을 것
      --> 개발자는 file에 몇개의 글자수가 있을지 모른다. 
      --> 이럴 경우, while문으로 file의 끝까지 읽어라 명령

 

1) for문

 for문은 반복횟수를 알고 있을 때 사용하기 용이하다.

 

(1) for문

 

- 양의 정수의 합 구하기 : 1+2+3+...+num

package practice;

public class SumTest {

	public static void main(String[] args) {
		int num = 10;
		int sum = 0;
		
		for(int i = 1; i <= num; i++)
		{
			sum += i;
		}
		System.out.println("sum : "+sum);
	}

}

>> 결과

sum : 55

 

- 짝수의 합 구하기 : 2+4+...+num / 1+3+...+num

package practice;

public class EvenOdd {

	public static void main(String[] args) {
		
		int num = 20;
		int sum = 0;
		
		//짝수의 합 구하기
		
		//방법1 _ if문 활용 
		//두번째 차례만 출력 : 1 (2) 3 (4) 5 (6)
		
		for(int i = 0; i <= num; i++)
		{
			if(i % 2 == 0)
			{
				sum += i;
			}
		}
		System.out.println("sum : "+sum);
		
		sum = 0;
		
		//방법2 _ for문 내 증감식 활용
		//증감을 +2씩 : 2 4 6 8 10 
		
		for(int i = 0; i <= num; i+=2)
		{
			sum += i;
		}
		System.out.println("sum : "+sum);
	}

}

>> 결과

sum : 110
sum : 110

 

- 'A'부터 'Z'까지 문자 출력하기 

(1) ASCII 코드 A : 65, Z : 90, a : 97임을 활용 
    pf. int ch = 'A'; 가 가능한 이유는? char은 JAVA에서 2byte이며, int는 4byte. 더 큰 타입으로는 자동 형변환
(2) System.out.printf의 형식지정자(formatter) %c 활용
    - System.out.printf("%c",65);  의 결과는 'A' 
    - System.out.printf("%d",'A'); 는 안 됨
      **why? 그렇게 메서드가 정의되어 있음. (외울 때 Tip. 출력은 디코딩이니 'A' -> %d는 안되는 걸로)
package practice;

public class CharTest {

	public static void main(String[] args) {
		//A부터 Z까지 출력
		//Ascii에서 A : 65, Z : 90, a : 97
		
		//방법1_아스키 10진수 직접 입력
		for(int i = 65; i <= 90; i++) {
			System.out.printf("%c",i);
		}
		System.out.println();
		
		//방법2_Char to Int 자동 형변환
		for(int i = 'A'; i <= 'Z'; i++) {
			System.out.printf("%c",i);
		}
		System.out.println();
	}

}

>> 결과

ABCDEFGHIJKLMNOPQRSTUVWXYZ
ABCDEFGHIJKLMNOPQRSTUVWXYZ

 

- 'A'부터 'Z'까지 중 3번째 차례 뒤에 구분문자(delim) 넣기

package practice;

public class CharTest2 {

	public static void main(String[] args) {
		//A~Z사이에 구분문자(delim) 넣기
		//ABC-DEF-....
		
		char delim = '-';
		
		//방법1_012-345... 
		//n번 반복/ n번 중 3의 나머지가 2일 때 delim (출력시 'A'+n)
		
		for(int j = 0; j < 26; j++) {
			if(j % 3 == 2) {
				System.out.printf("%c%c",'A'+j,delim);
			}else {
				System.out.printf("%c",'A'+j);
			}
		}
		System.out.println();
			
		//방법2_65 66 67 - 68 69 70 - ... 
		//n번 반복/'A'부터 'Z'중 3의 나머지가 1일 때 delim
		for(int i = 'A'; i <= 'Z'; i++) {
			if(i % 3 == 1) {
				System.out.printf("%c%c",i,delim);
			}else {
				System.out.printf("%c",i);
			}
		}
		System.out.println();
	}

}

>> 결과

ABC-DEF-GHI-JKL-MNO-PQR-STU-VWX-YZ
ABC-DEF-GHI-JKL-MNO-PQR-STU-VWX-YZ

 

 

(2) 중첩 for문

 

- 5x5 블럭쌓기 

package practice;

public class BlockTest {

	public static void main(String[] args) {
		
		int col = 5;
		int row = 5;
		
		for(int i = 0; i < row; i++) {
			for(int j = 0; j < col; j++) {
				System.out.print("*");
			}
			System.out.println();
		}
	}

}

>> 결과

*****
*****
*****
*****
*****

 

- 반 피라미드 블럭 쌓기

package practice;

public class BlockTest2 {

	public static void main(String[] args) {
		
		int row = 5;
		
		for(int i = 0; i < row; i++) {
			for(int j = 0; j <= i; j++) {
				System.out.print("*");
			}
			System.out.println();
		}
	}

}

>> 결과

*
**
***
****
*****

 

2) While문

- 반복횟수 모를 때에(파일 처리/키보드입력)

 

- 파일 읽기

(가정) 프로젝트 폴더에 "test.txt"에 아래와 같이 적었다고 가정

Hello,
my love
package practice;

import java.io.FileReader;
import java.io.IOException;

public class FileTest {

	public static void main(String[] args) throws IOException, InterruptedException {
		//파일을 읽어볼 때
		//io안의 클래스 FileReader
		    //메서드 read() - 파일읽기, close() - 파일닫기 
		FileReader file = new FileReader("test.txt");
		int ch = 0;
		int cnt = 0;
		
		//파일을 문자가 없을 때까지 한 문자씩 반복해서 읽고 출력
		//**몇개의 문자가 있을지 모른다.
		while(true) 
		{
			ch = file.read();
			
			if(ch == -1) break; //문자없을 때 반복문 나가기
			
			System.out.printf("%c",ch);
			Thread.sleep(100);
			
			cnt++;
		}
		System.out.println("\n-----------------------");
		System.out.println("총 문자 수 : "+cnt);
		
		file.close();
	}

}

>> 결과

Hello,
my love
-----------------------
총 문자 수 : 15

**** 총 문자 수가 15가 나온 이유 :

      ','과 공백 포함 보이는 문자는 13개 + Enter(실제 코드 : \r\n)   

                                                       <<--- \r,\n처럼 눈에 안 보이는 문자를 화이트 문자라고 한다.

 

- 키보드 입력

(아래 프로그램 흐름) 

※ 참조 : 키보드 버퍼, https://dogrushdev.tistory.com/39

자바 프로그램   RAM   외부 입력 장치
int ch System.in.read() 키보드 버퍼 키보드
  (문자 1byte씩 읽고
int형으로 return)
(임시 저장) (사용자가 입력 후 
엔터를 치면 버퍼로 이동)
package practice;

import java.io.IOException;

public class KeyBoardTest {

	public static void main(String[] args) throws IOException, InterruptedException {
		
		int ch;
		int cnt = 0;
		
		//사용자에게 입력 안내
		System.out.println("문자를 입력하세요.(종료 시 : Ctrl + Z)");
		
		//사용자가 Ctrl+Z를 누를 때까지 반복해서 버퍼 내용을 읽기
		while(true)
		{
			ch = System.in.read();
			
			if(ch == -1) break;
			
			System.out.printf("%c",ch);
			
			Thread.sleep(100);
			
			cnt++;
		}
		System.out.println("\n------------------");
		System.out.println("총 문자 수 : "+cnt);
	}

}

 

- 키보드 입력2 

package mymain;

import java.io.IOException;

public class _12_Ex_while3_키보드입력2 {

	public static void main(String[] args) throws IOException {
		//키보드 표준장치명 : System.in (byte씩 입력)
		  //사용자가 언제 끝낼 지 결정 - 개발자는 반복횟수 알 수 없음
		
		int ch;
		int total_count = 0; //총 입력 문자수
		int number_count = 0; //숫자문자 갯수
		int alpha_upper_count = 0; //대문자 갯수
		int alpha_lower_count = 0; //소문자 갯수
		int white_count = 0; //white문자 갯수 : (\r,\n,\t,'')
		int etc_count = 0; //나머지 문자 갯수
		
		System.out.println("값을 입력하세요(종료 : Ctrl + Z)"); 
		//운영체제의 CL(명령 라인)에서 Ctrl+z는 종료의 단축키
		
		while(true)
		{
			ch = System.in.read(); 
			
			if(ch == -1) break; //System.in.read()가 -1반환
			
			//총 입력 갯수 카운트(EOF 제외)
			total_count++;

			//수문자 갯수 카운트
			if(ch >= '0' && ch <= '9') 
				number_count++;
			
			//대문자 갯수 카운트
			else if(ch >= 'A' && ch <= 'Z') 
				alpha_upper_count++;
			
			//소문자 갯수 카운트
			else if(ch >= 'a' && ch <= 'z') 
				alpha_lower_count++;
			
			//白문자 갯수 카운트
			else if(ch == '\r' || ch == '\n' || ch == '\t'  || ch == ' ') 
				white_count++;
			
			//나머지 갯수 카운트
			else
				etc_count++;
			
			System.out.printf("%c",ch);
		}
		System.out.printf("전  체 갯수 : %2d\n",total_count);
		System.out.printf("숫  자 갯수 : %2d\n",number_count);
		System.out.printf("대문자 갯수 : %2d\n",alpha_upper_count);
		System.out.printf("소문자 갯수 : %2d\n",alpha_lower_count);
		System.out.printf("화이트 갯수 : %2d\n",white_count);
		System.out.printf("나머지 갯수 : %2d\n",etc_count);
		System.out.println("-----[END]-----");
		
		
	}

}

 

 

3) do-While문

- 반복횟수 모를 때에 용이
- 특정 명령을 행한 뒤(do), (사용자의 의사에 따라) 지속할 지 확인(confirm) 후 반복할 때 사용.
package practice;

import java.util.Scanner;

public class Dan99Test {

	public static void main(String[] args) {
				
		int dan = 0;
		String yn = "Y";
		Scanner scanner = new Scanner(System.in);
		
		do
		{
			System.out.print("단 입력(2~9단 중 하나) : ");
			dan = scanner.nextInt();
			
			if(dan >= 2 && dan <= 9) {
				for(int i = 1; i <=9; i++) {
					System.out.printf("%d x %d = %2d\n",dan,i,dan*i);
				}
				System.out.print("더 하시겠습니까? (y/n) :");
				yn = scanner.next();
			}else {
				System.out.println("2~9 중 하나를 입력해주세요.");
			}
		}while(yn.equals("Y") || yn.equals("y"));
			
		scanner.close();
	}

}

>> 결과

단 입력(2~9단 중 하나) : 10
2~9 중 하나를 입력해주세요.
단 입력(2~9단 중 하나) : 3
3 x 1 =  3
3 x 2 =  6
3 x 3 =  9
3 x 4 = 12
3 x 5 = 15
3 x 6 = 18
3 x 7 = 21
3 x 8 = 24
3 x 9 = 27
더 하시겠습니까? (y/n) :n

국비지원수업에서 배운 연산자에 대해서 이론적인 부분을 복습해보았다..

 

-------------------------------------------------------------------------------------------------------------------------------

 

[연산자의 종류]

- 연산을 할 때는 1) 우선순위, 2)자료형을 고려해야 한다. 

우선순위 단항연산자   연산순서
높음 최우선 연산자 (괄호)  
단항연산자 ~, !, ++, --, (cast), -(부호) <--
산술연산자 + , - , * , /(몫) , %(나머지) -->
쉬프트 연산자
(=2진 연산자)
>>, <<, >>> -->
관계 연산자 >, >=, <, <=, ==, != -->
이진논리연산자 &, ^, |,  >> -->
일반논리연산자 &&(AND), ||(OR) -->
삼항연산자 (조건) ? 값(참) : 값(거짓) <--
대입연산자 =  
낮음 (복합 대입 연산자) +=, -=, *=, /=, %=, &=, ^=, |=, >>=, <<= <--

 

1. 단항 연산자 : ~, !, ++, --, (cast), -(부호)

> 단항의 앞에 사용하는 연산자이다.

 

(1) ~ (tilde) : 이진 논리 Not 연산자 (1의 보수)

//Tilde ~ : 2진수로 표현했을 때의 1의 보수

class Tilde{
	public static void main(String[] args){
    	int n = 10; 
		System.out.printf("[%32s]\n",Integer.toBinaryString(n));
		System.out.printf("[%32s]\n",Integer.toBinaryString(~n));
    }
}

>> 결과

[                            1010]
[11111111111111111111111111110101]

 

(2) ! : 일반논리 Not연산자

class NotOperator{
	public static void main(String[] args){
    	boolean bOk = !(3>2); //boolean bOk = !3>2; 는 불가 why? 일반논리일 경우에만 !사용 가능
		                      //(3>2) == true
		System.out.printf("!(3>2) : %b\n",bOk);
		System.out.printf("!true : %b\n",!true);
    }
}

 

>> 결과

!(3>2) : false
!true : false

 

(3) ++(증가), --(감소) : 증감 연산자

- 전위형 : ++n --> 산술연산, 명령이 있기 전에 먼저 변수값을 +1한다. (먼저 변수값을 +1)

- 후위형 : n++ --> 산술연산, 명령이 있은 후에 변수값을 +1한다. (마지막에 변수값을 +1)

public class PlusplusOperator {

	public static void main(String[] args) {
		int x = 1;
        int y = 2;
        int z;
        
        z = ++x + y++;
        System.out.printf("x : %d, y : %d, z : %d\n",x,y,z);
	}

}

>> 결과

x : 2, y : 3, z : 4

//z = ++x + y++; 의 연산 순서   
//1) ++x                 --- > x = x + 1;  //2
//2) x + y               --- > 2 + 2
//3) z = x + y           --- > z = 4;
//4) y++                 --- > y = y + 1;  //3

 

(4) -(부호) : (-1)을 곱해주는 연산자

 

(5) 강제 형변환 연산자 : cast 연산자

Casting

1. 자동 형변환 
   1) 연산시 : 자료형이 큰 쪽으로 자동 형변환
   2) 대입시 : '='를 기준으로 좌변항이 더 큰 자료형일 경우 좌변형의 자료형으로 자동 형변환

2. 강제 형변환 : '(자료형) 변수' 형식

**자동 형변환시, 프로모션(큰쪽으로 형변환)된다.
**강제 형변환시, 디모션(작은쪽으로 형변환)이 가능하나, 오버플로우의 가능성을 염두해야한다.

 

2. 산술연산자 : 사칙연산

- 사칙연산 시, 위의 Casting 방식에 따라 자동 형변환이 이루어짐.

** int보다 작은 정수형 자료형의 경우, 사칙연산 시 결과가 int형으로 나타남

  ex. byte + byte = int 

  why? 중앙처리장치 안의 연산기(ALU)를 통해 연산이 이루어지는데, 계산 시 4byte단위로 결과를 냄 

  ---> 결과적으로 int 타입으로 변환

 

3. 쉬프트연산자(=2진 연산자) : 2진수로 표현한 값에서 >>우측으로 가고, <<좌측으로 가기

- >> : 우측으로 가고, 앞쪽을 부호로 채우기

- << : 좌측으로 가고, 뒤쪽을 0으로 채우기

- >>> : 우측으로 가고, 앞쪽을 0으로 채우기

 

4. 관계연산자 : >, >=, <, <=, ==, !=

 

5. 이진논리연산자 

package mymain;

public class _05_이진논리연산자 {

	public static void main(String[] args) {
		//5. 이진논리연산자
		System.out.printf("[%32s]\n",Integer.toBinaryString(7));
		System.out.printf("[%32s]\n",Integer.toBinaryString(5));
		
		System.out.printf("[%32s]\n",Integer.toBinaryString(7&5));
		System.out.printf("[%32s]\n",Integer.toBinaryString(7|5));
		System.out.printf("[%32s]\n",Integer.toBinaryString(7^5));
		
		// & ^ | >>의 활용 사례
		
		int birthday = 0x19880815; //실제로 birthday일케 안씀... 4bit가 8개.. 32bit --> int 형
		
		System.out.printf("생년월일 : %x\n",birthday); // 19880805 '0805'제외 하고자함
		
		  //출생년도 추출
		int year = birthday >>> 16; // 16bit만큼 밀기 (16진수 하나당 4bit * 4), 앞 공간(부호영역) 양음수 상관없이 0으로 채워짐
		System.out.printf("출생년도 : %x년\n",year);
		
		  //출생월 추출
		             //0x00198808               
		int month = birthday >>> 8 & 0x000000ff;   //소거(0일때 거짓, 1일때 참. 0&0=0. 1&1=1 >> 1이 있는 쪽은 살아남)
		System.out.printf("출생월 : %02x월\n",month);
		
		  //출생일 추출
		int day = birthday & 0xff;
		//int day = birthday & 0x000000ff; 
		System.out.printf("출생월 : %02x일\n",day);
		
		  //출생연월도에서 월을 수정 - 기존 : 0x19980815
		  //1. 월의 자리를 소거 (^)  -- ^은 서로 배타적일 때 참(1), 그렇지 않으면 거짓(0) >> 1010과 1010은 같음 --> 0000이 됨
		birthday = birthday ^ 0x0000800;
		System.out.printf("생년월일 : %x\n",birthday);
		
		  //2. 추가하고 싶은 월 값 추가 (현재 : 0x19880015)   0 : 0000   5 : 0101
		  //                    |       0x00001100    1 : 0001   0 : 0000
		  //                                              0001       0101
		birthday = birthday | 0x00001100; // |는 추가(0 또는 1 = 1 >> 1010 또는 1001은 1011) 
		System.out.printf("생년월일 : %x\n",birthday);
	}

}

>> 결과

[                             111]
[                             101]
[                             101]
[                             111]
[                              10]
생년월일 : 19880815
출생년도 : 1988년
출생월 : 08월
출생월 : 15일
생년월일 : 19880015
생년월일 : 19881115

 

6. 일반논리연산자 : &&(AND), ||(OR)

- 일반논리연산자는 경제적 연산을 한다.

▼ 아래를 보면 경제적 연산을 하기 때문에 dead code 발생

class AndOr{
	public staitc void main(String[] args){
        System.out.println("----[&&]----");
        System.out.printf("true && true : %b\n", (true && true));
        System.out.printf("true && true : %b\n", (true && false));
        System.out.printf("true && true : %b\n", (false && true)); //Alert : Dead Code 
        System.out.printf("true && true : %b\n", (false && false));//Alert : Dead Code 

        System.out.println("----[||]----");
        System.out.printf("true || true : %b\n", (true || true));  //Alert : Dead Code  
        System.out.printf("true || true : %b\n", (true || false)); //Alert : Dead Code 
        System.out.printf("true || true : %b\n", (false || true));  
        System.out.printf("true || true : %b\n", (false || false));
    }
}

- 일반논리연산자 예제 ) 윤년/평년 구하기

package mymain;

import java.util.Scanner;

public class _08_일반논리연산자응용2 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner scanner = new Scanner(System.in);
		
		int year;
		System.out.print("연도 : ");
		year = scanner.nextInt();
		
		//윤년/평년
		//윤년 조건
		//조건1. 400의 배수가 되는 해 (ex.400년, 800년...2000년)
		//또는
		//조건2. 4의 배수이면서 100의 배수가 아닌 해 
		
		if((/*조건 1*/year%400==0) || (/*조건2*/year%4==0 && year%100!=0)) {
			System.out.printf("[%d]년도는 [윤년]입니다.\n",year);
		}else {
			System.out.printf("[%d]년도는 [평년]입니다.\n",year);
		}
		
		scanner.close();
	}

}

>> 결과

연도 : 2022
[2022]년도는 [평년]입니다.

 

7. 삼항 연산자 : (조건) ? 값(참) : 값(거짓)

class threeOperator{
	public static void main(String[] args){
    	int x = 10;
        int y = 4;
        String z;
        
        z = (x % y ==0)? "맞다" : "아니다";
        
        System.out.printf("%d는 %d의 배수가 %s", x, y, z);
    }
}

>> 결과

10는 4의 배수가 아니다

 

8. 대입 연산자 : =

 

9. 복합 대입 연산자 : +=, -=, *=, /=, %=, &=, ^=, |=, >>=, <<=

int n;
n = 10;
		
n++; // n = n + 1;
n+=2; // n = n + 2;
n-=3; // n = n - 3;

 

 

----------------------------------------------------------------------------------------------------------------------------------

 

[연산자를 활용한 코드 예시]

 

1. 지폐/동전 갯수 세는 코드 

- 산술연산자 /와 %를 활용했을 때에 계산이 간편해짐을 볼 수 있다.

package mymain;

import java.util.Scanner;

public class MoneyCnt {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner scanner = new Scanner(System.in);
		int input;
		int tmp;
		int[] moneyArr = {50000, 10000, 5000, 1000, 500, 100, 50, 10}; 
		int[] cntArr = new int[9];
		
		//사용자에게 금액 받기
		System.out.print("금액 : ");
		input = tmp = scanner.nextInt();
		
		//화폐 갯수 세기 : 5만권부터 /와 % 연산자로 갯수 세기
		for(int i = 0; i < moneyArr.length; i++) {
			cntArr[i] = tmp / moneyArr[i];
			tmp = tmp % moneyArr[i];
		}
		
		System.out.printf("---%d(원)에 대한 권종별 갯수---\n",input);
		System.out.printf("50000원 : %d(매)\n",cntArr[0]);
		System.out.printf("10000원 : %d(매)\n",cntArr[1]);
		System.out.printf(" 5000원 : %d(매)\n",cntArr[2]);
		System.out.printf(" 1000원 : %d(매)\n",cntArr[3]);
		System.out.printf("  500원 : %d(개)\n",cntArr[4]);
		System.out.printf("  100원 : %d(개)\n",cntArr[5]);
		System.out.printf("   50원 : %d(개)\n",cntArr[6]);
		System.out.printf("   10원 : %d(개)\n",cntArr[7]);
		System.out.printf("    1원 : %d(개)\n",cntArr[8]);
		
		scanner.close();
	}

}

 

>> 결과

금액 : 258439
---258439(원)에 대한 권종별 갯수---
50000원 : 5(매)
10000원 : 0(매)
 5000원 : 1(매)
 1000원 : 3(매)
  500원 : 0(개)
  100원 : 4(개)
   50원 : 0(개)
   10원 : 3(개)
    1원 : 0(개)

 

2. 섭씨를 화씨로, 화씨를 섭씨로 변환하기 

- 연산자를 사용할 때에 1) 연산 우선순위와 2) 자료형을 고려해야하는 이유를 볼 수 있다.

**잘못된 연산 순서와, 잘못된 자료형의 사용은 잘못된 결과를 나오게 함.

public class FarenCel {

	public static void main(String[] args) {
		// 온도변환
		// 섭씨 -> 화씨 : F = 9/5 * C + 32;
		// 화씨 -> 섭씨 : C = 5/9 *(F-32);
		
		double cel = 7.0;
		double far = 44.6;
		FarenCel.toFar(cel);
		FarenCel.toCel(far);	
	}
	static void toFar(double cel) {
		double result = (cel * 5/9) + 32;
		            //= (double *(int/int)) + int;
		            //= (double * double) + int;
		            //= double + int;
		System.out.printf("섭씨 [%.1f] = 화씨 [%.1f]\n", cel, result);
	}
	static void toCel(double far) {
		double result = (far - 32) * 5/9;
		System.out.printf("화씨 [%.1f] = 섭씨 [%.1f]\n", far, result);
	}
}

>> 결과

섭씨 [7.0] = 화씨 [35.9]
화씨 [44.6] = 섭씨 [7.0]

 

[ Scanner 클래스의 입력 메서드 ]

/*아래의 경우, 
  키보드 버퍼에서 입력구분자(공백 또는 엔터) 전까지 가져온다.*/
next();
nextInt();
nextDouble();
nextBoolean();

/*nextLine();의 경우,
  키보드 버퍼에서 입력구분자(엔터)까지 가져온다. */
nextLine();

1. nextLine()

▼ nextLine() : 입력구분자(엔터)까지 가져옴(ex.홍길동E) --> E빼고 나머지 출력

nextLine()가 홍길동E를 가져옴

 

2. nextDouble() --> nextLine()

▼ nextDouble() : 입력구분자(공백 또는 E) 전까지 가져옴 

▼ nextDouble() --> nextLine() : 앞전에 남은 E를 nextLine()이 가져옴

//해결방법 : scan.nextLine()을 다음에 적어줌

package mymain;

import java.util.Scanner;

public class PrintTest {

	public static void main(String[] args) {
		Scanner scan = new Scanner(System.in);
		
		//콘솔창 입력 : 이름, 나이, 주소, 키, 몸무게
		System.out.print("이름 : ");
		String name = scan.nextLine();
		
		System.out.print("나이 : ");
		int age = scan.nextInt();
		scan.nextLine();
		
		System.out.print("주소 : ");
		String addr = scan.nextLine();
		
		System.out.print("키 : ");
		double height = scan.nextDouble();
		
		System.out.printf("몸무게 : ");
		double weight = scan.nextDouble();
		
		System.out.printf("기타 : ");
		double extra = scan.nextDouble();
		
		scan.close();
		
		//출력
		System.out.printf(" 이름 : %s\n",name);
		System.out.printf(" 나이 : %d\n",age);
		System.out.printf(" 주소 : %s\n",addr);
		System.out.printf("  키 : %.3f\n",height);
		System.out.printf("몸무게 : %.3f\n",weight);
		System.out.printf("기타 : %.3f\n",extra);
	}

}

>> 콘솔 입력 + 결과

이름 : 홍길동
나이 : 30
주소 : 서울시 모모구
키 : 160
몸무게 : 99
기타 : 45
 이름 : 홍길동
 나이 : 30
 주소 : 서울시 모모구
  키 : 160.000
몸무게 : 99.000
기타 : 45.000

 

3. nextDouble() --> nextDouble()

▼ nextDouble() : 입력구분자(공백 또는 E) 전까지 가져옴 

▼ nextDouble() --> nextDouble() : 앞전의 E는 삭제되며, 새로 입력한 텍스트 입력구분자 전까지 가져옴

 

▼ 부스트 코스의 [쉽게 배우는 자바1], [JAVA의 정석], 국비지원과정을 들은 후 정리한 내용입니다.

------------------------------------------------------------------------------------------------------------

1. 프로그램 실행구조

프로그램 실행 구조도 (원본출처는 국비 강사샘.. 위는 샘이 그린 걸 제식대로 수정한 것.)

 

2. 변수(Variable)

(1) 변수란?

: 변수란, 단 하나의 값을 저장할 수 있는 메모리 공간을 의미한다.
: 변수는 상수(constant)와 다르게 변화할 수 있는 수이다.


[※ 참조하기 : 메모리의 논리적 구조, 정수형과 실수형 데이터]









 

 

(2) 변수의 선언과 초기화

 

가. 변수를 선언 : int(변수타입)에 age(변수이름)을 적고 ;로 마침표를 찍는다.

 

나. 변수의 초기화 : 변수 선언 후 처음으로 값을 넣어주는 것

- 변수를 선언한 이후에 변수 안에 값을 넣어주어야 한다. 그렇지 않을 경우, 다른 프로그램에서 작성한 '알 수 없는 값(쓰레기 값)'과 충돌할 수 있다.
> int age = 25;

 

다. 서로 다른 두 변수의 값을 교환하는 방법 :

public class Variable
{ 
    public static void main(String [] args)
    { int x = 25; 
      int y = 30; 
      int tmp; tmp = x; 
      x = y; 
      y = tmp; 
    } 
}

 

라. 변수의 명명규칙

- 변수를 포함하여 프로그램에 사용하는 모든 이름은, '식별자(identifier)'라고 한다.
- 프로그램을 작성할 때는 항상 식별자 명명 규칙을 따라야 한다.
식별자(사용자 정의 명칭) 명명 규칙

1. 대소문자가 구분되며 길이에 제한이 없다.
- true와 True는 서로 다름
2. 예약어를 사용해서는 안된다.
- true는 예약어, True는 예약어가 아님
3. 숫자로 시작해서는 안된다.
- name1은 가능함, 1name은 불가능
4. 특수문자는 '_'와 '$'만 허용한다.

* 예약어란? 키워드 또는 리저브드 워드라고 함. 프로그래밍언어의 구문에 사용되는 단어를 의미

* 사용자 정의 명칭이란? 클래스명/메소드명/변수명/상수명 등...

* 추가적으로, 변수명 중간에 공백을 띄우면 안 됨.. (ex. myName (o), my Name(x))

 

(선택사항) 그 외 자바 프로그램어들에게 권장되는 규칙

1. 클래스의 첫 글자는 항상 대문자로 한다.
- 반면, 변수와 메서드 이름의 첫글자는 항상 소문자로 한다.
2. 여러 단어로 이루어진 이름은 결합되는 단어의 첫 글자를 대문자로 한다.
- 클래스명 :
  1) Pascal 표기법 : ex. StringBuffer
  2) Pascal+snake 표기법 : ex. String_Buffer
- 메소드명/변수명 : 
  1) Camel 표기법 : ex. myMoney
  2) Snake 표기법 : ex. my_money 
3. 상수의 이름은 모두 대문자로 한다. 여러 단어로 이루어진 경우 '-'를 사용
ex. PI.MAX_NUMBER //snake표기법

* 자바에서는 모든 이름에 유니코드에 포함된 문자를 사용할 수 있으나, 가능한 클래스이름은 영문자로 하는 것이 좋다. 

* 패키지명은 대체로 소문자로 작성한다.

[※ 참고 : 기타 변수 표기법]

- 헝가리언 표기법 : 변수 앞에 접두어를 붙여 변수 성격을 표현

boolean bOk = "파리"=="새"; 
int nMoney = 100; 
char *pName = "홍길동"; //c언어 

 

(3) 변수 타입

※ 참조 : https://forsee.tistory.com/1

 

가. 데이터 타입

- 데이터 타입 :

값(data) 문자   'A', "ABC"
숫자 정수 -1, -2, 0, 1, 2
실수 1.23456, 5 X 10^2

- 변수를 선언할 때는, 저장하려는 값의 데이터 타입에 따라 변수 타입을 지정한다.


1) 기본형 변수(primitive type)

- 실제 값을 저장하며 연산이 가능하다.

크기 종류 자료형 Wrapper byte 표현 범위 연산/변환 출력서식 초기값
작다











크다
논리형 boolean Boolean 1 false, true X %b or %B flase
문자형 char Charater 2 0~65535  O %c '\u0000'
정수형 byte Byte 1 -128 ~ 127  O %d
(Decimal)
%o
(Octal)
%x
(Hexa)
0
short Short 2 -32768 ~ 32767  O
int Integar 4 -21 ~ 21  O
long Long 8 20자리 O 0L
실수형 float Float 4 10^-38~10^38 *정밀도 6-7 O %f 0.0f
double Double 8 10^-308~10^308 *정밀도 9 O 0.0d 또는 0.0

* 문자는 ascii코드에 따르면 1byte나, 자바는 유니코드를 따르므로 위에서 UTF-16 유니코드 기준 2byte로 쓰인 것
* JDK가 UTF-16에 따라 문자 인코딩(문자ㅡ숫자임, 0과 1로 인코딩) , 이것을 각 운영체제에 따라 화면에 디코딩할 때는 JVM이 동작하는 시스템에 따름.
* char은, 유니코드에 의해 정수형으로 컴퓨터에 저장되기 때문에 연산/변환 가능하나, string은 배열이기에 불가
* 정밀도가 높을 수록 오차범위가 낮음. 정밀도 = 7은, 10진수로 7자리 수를 오차 범위 없이 저장할 수 있다는 뜻

[※ 참고 : Scanner의 입력메서드 - next(), nextInt(), nextDouble(), nextBoolean(), nextLine()
- java.util.Scanner : java > util > Scanner클래스 
- Scanner의 next()와 nextLine()의 차이 : https://why-dev.tistory.com/21

[※ 참고 : System.out의 출력메서드 - print(), println(), printf() 설명]
- link : https://www.geeksforgeeks.org/difference-between-print-and-println-in-java/
- print(), println(), printf()로 콘솔창에서 받은 텍스트를 출력 가능 
- 3가지 모두 여러 자료형(char,char[],boolean,int,double...)을 받을 수 있도록 오버로딩되어 있음

1. print()와 println()의 차이
1) print();   : 텍스트 출력 후 콘솔창 끝에 커서가 남음(줄바꿈x) //다음 printinf은 여기서 시작
2) println(); : 텍스트 출력 후 다음줄로 이동

2. printf()의 출력서식
1) 정수형
     %d : decimal, 10진수로 출력. 
  %20d : 전체자릿수 20개 중에서 우측정렬로 10진수 출력
 %020d : 전체자릿수 20개 중에서 우측정렬로 10진수 출력하되, 공백은 0으로 채우기
 %-20d : 전체자릿수 20개 중에서 좌측정렬로 10진수 출력

2) 실수형 
     %f : 실수형으로 출력.
   %n.f : 전체자릿수 n만큼 출력, 우측정렬
%n.mf : 전체 자릿수 n중에서 소수점은 m만큼 출력, 우측정렬 //n보다 m이 크면 n 무시

3) 문자열 
 %20.5s : 전체 20개의 문자 중에 5개만 출력
package mymain;

import java.util.Scanner;

public class PrintTest {

	public static void main(String[] args) {
		Scanner scan = new Scanner(System.in);
		String input = scan.nextLine();
//              int num = Integer.parseInt(input); 
		double num = Double.parseDouble(input);
		scan.close();     //이걸 안하면, resource leak : scan is never closed 나타남
		
//		System.out.printf("[%d]\n",num);
//		System.out.printf("[%20d]\n",num);
//		System.out.printf("[%020d]\n",num);
//		System.out.printf("[%-20d]\n",num);
		
		System.out.printf("[%-10.3f]\n",num);
		System.out.printf("[%-3.4f]",num); //전체자릿수 무시
	}

}

>> 결과

3.56549884846546564
[3.565     ][3.5655]

>> 위에서 //부분을 활성화하고 아래는 주석처리하면 결과는

[20]
[                  20]
[00000000000000000020]
[20                  ]

 

 

package mymain;

import java.util.Scanner;

public class PrintTest {

	public static void main(String[] args) {
		Scanner scan = new Scanner(System.in);
		String input = scan.nextLine();
		scan.close();
		
		System.out.printf("[%20.3s]\n",input);
	}

}

>> 결과

// 입력 : 가나다라마바사아자차카타파하
[                 가나다]

 

2) 참조형 변수(reference type)

- 변수의 타입으로 클래스를 가지며, NULL을 포함한 객체의 주소(4byte, 0x0~0xffffffff)를 가짐
*단, JVM이 32bit가 아니라, 64bit일 경우, 객체의 주소 곧, 참조형 변수의 크기는 8byte임
- 참조형 변수는 컴퓨터공학에서 보았던 포인터 같다. 자바에서는 이 포인터가 (일종의 설계도인) 클래스의 객체들이 있는 주소를 담는다(=가리킨다)는 점에서 약간의 차이가 있어 보인다.
- 예시

Date today = new Date();

- 컴퓨터 공학에서 C언어를 통해 포인터로 메모리를 할당했던 것과 비교

//기본형 변수 : 변수는 기본형 값을 갖음
int number = 2; 
int p = &number; //p는 number의 주소를 담고 있음. 

//참조형 변수 : 변수는 할당받은 공간을 가리키는 주소값을 갖음
int *p = malloc(sizeof(int));

//주소는 운영체제의 크기에 따라서 32bit, 64bit가 될 수 있음

 

3) 오버 플로우

- 데이터 타입에 따라 변수가 가질 수 있는 저장공간이 지정되는데, 그 이상으로 값을 넣는 경우 오버플로우 발생

 

나. 상수와 리터럴(Constant & Literal)

(1) 상수 : 값을 한 번 저장하면 변경할 수 없는 저장 공간

- 변수 타입 앞에 final를 붙여 선언
- 상수는 모두 대문자로 작성하는 것이 관례이며, 길어질 경우 _로 구분

final int MAX_SPEED = 200;

(2) 리터럴 : 실질적인 값

- 수학에서 말하는 상수
- 위 박스 안의 200도 리터럴이고, 변수 안에 넣는 숫자도 리터럴
- final int FIRST_NAME = 'c'; 이면, 여기서의 'c'도 리터럴
▶ 리터럴의 타입과 접미사

종류 리터럴 접미사
논리형 false, true 없음
정수형 123, 0b0100, 077, 0xFF, 100L L
실수형 3.14, 3.0e8, 1.4f, 0x1.0p-1 f(float), d(생략가능)
문자형 'A', '1', '\n' 없음
문자열 "ABC", "1234", "A" 없음

* 실수형의 경우, 소수점만 적어도 되며, e를 통해서 10의 제곱을 표현할 수 있다.

int small = 12345; 
long big = 85_000_000_000L; 
float less = 0.345f; 
double more = 0.3456788999; 
more = 34.56788999e-2;


▶ 타입이 불일치 해도 사용이 가능한 경우 : 타입이 달라도 저장범위가 넓은 타입에 좁은 타입을 저장하는 경우

int firstIndex = 'A'; //A는 유니코드로 65를 의미함 

double Serial = 23456; //float을 double에 넣는 경우
[※ 참고하기 : ASCII코드] 

ASCII코드(통신문자코드) : 0~126

0~31 : 통신 및 제어문자
    '\r' : carriage return(Home) = '\r\n' : 맨 앞으로 가라, 그리고 엔터해라
    '\n' : new line(Enter)
    '\t' : tab key
    '\b' : caret(커서)의 위치를 이전으로 이동
    '\a' : alert경고음
    '\f' : 다음장으로 이동해라.

32~126 : 키보드상 문자코드
    '  ' : 32
    'A' : 65
    'a' : 97 //소->대문자 간격 : 32
    '0' : 48
    '1' : 49

문자 출력시에 
System.out.printf("%c\n",65); 가능하지만,
System.out.printf("%d\n",'한'); 은 불가능.

 

다. 문자 리터럴과 문자열 리터럴

 

(1) JAVA언어에서 String은 클래스를 의미한다.

- 컴퓨터 공학에서 string은 사실상 배열이었다. 그리고 string을 C언어로 표현하기 위해서는 char *name = " "; 처럼 표현을 했다. 만약 string을 쓰고 싶다면 #include 를 통해 string을 선언한 라이브러리를 가져와야 했다.
- 마찬가지로 JAVA언어에서도 string은 문자데이터들이 모인 공간, 곧 배열을 의미한다.
- 따라서 원칙적으로 String은 아래처럼 표현해야 하는 것이 맞다.
- 다만 java에서는 기본적으로 내장되어 있는 클래스가 있어서, String name = " "; 도 허용한다.

String name = new String("JAVA");

 

(2) 문자열의 결합

- + 연산자는 왼쪽에서부터 오른쪽으로 연산을 수행한다.
- JAVA에서는 +연산자를 활용해 [문자열 + 문자열]을 할 수 있으며, 문자열이 아닌 다른 타입과 결합할 경우 순차적인 연산을 이어가며 최종적으로는 문자열로 변환한다.

public class Variable
{ 
   public static void main(String[] args) 
   { 
      String name = "홍길동"; 
      System.out.println(1+name);
      System.out.println(name+1); 
      System.out.println(1+1+name); 
      System.out.println(name+1+1); 
   } 
}

>> 결과

1홍길동 
홍길동1 
2홍길동 
홍길동11

 

(3) 특수문자를 표현하는 방법

특수문자 문자 리터럴
줄바꿈 \n
역슬래쉬(\) \\
작은따움표 \"
큰따움표 \'


라. 형변환(Casting) : 변수 또는 상수의 타입을 다른 타입으로 변환시키는 것
- 형변환 규칙

1. boolean을 제외한 나머지 7개의 기본형은 서로 형변환이 가능하다.
2. 기본형과 참조형은 서로 형변환할 수 없다.
3. 서로 다른 타입의 변수간의 연산은 형변환을 하는 것이 원칙이지만, 값의 범위가 작은 타입에서 큰 타입으로의 형변환은 생략할 수 있다.

- 아래와 같이 x의 값을 가져다가 y로 형변환을 해서 가져갈 경우, x값은 그대로 남고 y에 값을 복사해서 준다.

public class Variable
{ 
   public static void main(String[] args) 
   { 
     double x = 2.23356; 
     int y = (int)x; 
     System.out.println(x); 
     System.out.println(y); 
   } 
}

>> 결과

2.23356 
2

**정수형 int를 실수형으로 바꿀 때, float으로 바꿀 경우, int는 정밀도가 10인데 float은 8이라 오차가 발생할 수 있다. 따라서, int를 실수로 바꿀 때는 double을 쓰는 것이 좋다.

 

3. 연산자(Operator)

(1) 연산자의 종류
- 연산자 : 연산을 수행하는 기호
- 피연산자 : 연산자의 작업 대상(변수, 상수, 리터럴, 수식)

종류 연산자 설명
산술 연산자 +, -, *, /, %, <<, >> 사칙연산 및 나머지(%)
비교 연산자 >, <, >=, <=, ==, != 크기
논리 연산자 &&, \\, !, &, \, ^, ~ AND, OR
대입 연산자 = 우변의 값을 좌변에 저장


(2) 연산자의 결합 규칙(우선순위)

1. 산술 > 비교 > 논리 > 대입 순의 연산 우선순위
2. 단항 > 이항 > 삼항. **단항은 -3과 같이 피연산자가 하나인 것
3. 단항 연산자와 대입 연산자를 제외한 모든 연산의 진행방향은 왼쪽에서 오른쪽 *단항과 대입은 반대


(3) 산술 변환
- 두 피연산자의 타입이 같아야 산술 연산이 가능함 (형변환 연산자로 타입 일치 필요)
- 단, 작은 타입에서 큰 타입으로 형변환을 할 경우, 자동적으로 형변환이 이루어지므로 형변환 연산자 생략 가능
▶ 자동 산출 변환 규칙

1. 두 피연산자의 타입이 다를 경우, 보다 큰 타입으로 일치시킨다.
2. 피연사자의 타입이 int보다 작은 타입이면 int로 변환된다.
ex. short + byte = int + int = int
char + byte = int + int = int

- (주의) 연산결과의 타입이 피연산자와 다른 경우를 유의해야 한다.
ex. (int) 5 / (int) 2 = 2.5 의 경우, 둘 중에 하나를 (float)으로 형변환하여야만 함

>>산술 변환 외에 비교/논리/대입은 차후에 다시...

(4) 메서드를 사용한 연산 :
- Math.를 사용하여 사칙연산 외에 계산이 가능하다. (반올림이나 단순 비교 등)

public class Datatype
{ 
  public static void main(String[] args) 
  { //둘 중에 큰 수 출력 
    System.out.println(Math.max(9, 5)); 
    //올림 
    System.out.println(Math.floor(2.85786)); 
    //앞 수를 뒤 수로 나눈 값의 반올림 
    System.out.println(Math.floorDiv(18, 7)); 
  } 
}

 

1. 처음으로 코드 작성해보기 - System.out.prinlin("  ");

public class HelloWorldApp {
	//C언어의 int main(void) 함수 역할을 하는 녀석
	public static void main(String[] args) {
		//println = print line
		System.out.println("hello World!!");
	}
}

>> 결과

Hello World!!

 

 

2. 소스코드 컴파일링 & 실행

 

[방법1.에디터 미사용] 메모장을 이용해 컴파일 후 실행하기

* C언어에서는 clang 또는 make 명령어를 사용해서 컴파일을 했다면, JAVA는 javac를 사용해 컴파일을 한다.

 

가. cmd 경로 변경 : 소스코드(.java)가 있는 위치로 가기
**폴더명 다 치지 않고 일부만 친 후 + tab치면 알아서 폴더명 잡아줌
1) 폴더 하나씩 cd + 폴더명 칠 수도 있고
2) 한 줄로 다 칠 수도 있고
3) 폴더 경로 드래그에서 붙일 수도 있다.

나. 컴파일 하기 : javac/javac.exe + 자바파일명.java (ex. java.exe Hello.java)

*컴파일이란? 고급언어인 소스코드를 저수준언어로 변환하는 과정

*저수준 언어 = 실행파일 = binary code = byte code : .class형태로 저장된 파일 내용
1) javac.exe Hello.java 입력
2) javac Hello.java 입력

 

[※ 참고하기 : .java와 .class 의 구성내용 확인]

- 코드내용을 확인할 때 --- type 명령어 사용 ex. type Hello.java

- 아래를 보면 type Hello.java를 했을 땐 소스코드를 볼 수 있고,

- type Hello.class를 했을 때 알 수 없는 코드가 나오는 걸 볼 수 있다.

- 컴퓨터 공학에서 배웠던 C언어 컴파일링의 단계는 총 4단계로, 

  1) 전처리(Precompile) : 실질적인 컴파일링 전 #include와 같이 #이 들어간 코드에 대한 선작업을 먼저 해준다.

  2) 컴파일(Compile) : 어셈블리어라는 저수준 프로그래밍 언어로 컴파일

  3) 어셈블(Assemble) : 어셈블리 코드를 오브젝트 코드로 변환시켜주는 것. 중앙처리장치가 이해할 수 있는 0,1로 변경

  4) 링크(Link) : cs50.h나 math.h와 같이 여러개의 파일로 이루어진 경우, 이를 하나의 오브젝트 파일로 연결

  였다. 위에서도 보면 컴파일을 하게 되면 저수준 언어로 변경되는 걸 볼 수 있다.

[※ 추가 참고하기 : 프로그래밍 언어의 발전 역사]

1세대 언어 : 어셈블리어 (기계와 밀접한관계)
2세대 언어 : 인터프리터 (실시간 해석언어) - html, javascript 브라우저가 한줄씩 해석
3세대 언어 : 컴파일러 언어 
** C언어는 소스코드를 컴파일(전체 해석)하고 컴파일한 것을 컴퓨터가 바로 실행
** 자바는 JVM이 소스코드 한줄에 대한 컴파일코드에 대해 한줄씩 실행 (인터프리터 장점 + 컴파일러 언어 장점)
** 컴파일러 언어는 속도는 빠르지만 실시간 한줄 실행이 아니라 메모리 공간을 크게 사용할 수 밖에 없음
** 인터프리터는 실시간으로 해석하면서, 필요하면 공간을 만들고 아니면 안 쓸 수 있어 속도는 느려도 공간 활용이 좋음

 

[※ 참고하기 : .java 파일저장 및 컴파일 중 인코딩 타입 에러가 난 경우]

(ex. 한글을 넣었는데, 인코딩 타입이 UTF-8이 아니라 다른 거라며 버그가 나타남)

- javac -encoding utf-8 파일명.java

- 추가 참조 링크 : https://breathtaking-life.tistory.com/96

UTF-8로 인코딩 되게 .java 저장함
컴파일을 하니, 한글을 못읽는다.&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;nbsp;
문제는 컴파일 과정에 있던 모양이다. javac 뒤에 -encoding utf-8을 추가하여 해결했다.

 

다. 실행하기 - java + 클래스파일명 (ex. java Hello)

-  cmd에서 javac 명령어로 컴파일 할 때 확장자는 쓰지 않는다. 

 

 

[방법2. 에디터 사용] 이클립스를 활용해 컴파일 후 실행하기

 

가. 이클립스 설치하기

- 다운로드 링크 : https://www.eclipse.org/downloads/packages/

 

Eclipse Packages | The Eclipse Foundation - home to a global community, the Eclipse IDE, Jakarta EE and over 350 open source pro

509 MB 785,390 DOWNLOADS Tools for developers working with Java and Web applications, including a Java IDE, tools for JavaScript, TypeScript, JavaServer Pages and Faces, Yaml, Markdown, Web Services, JPA and Data Tools, Maven and Gradle, Git, and more. Cli

www.eclipse.org

 

나. 이클립스 실행하기 - 워크 스페이스 경로 설정

- 처음 이클립스 실행하면 디폴트 저장 경로를 설정할 수 있다. 

 

다. 프로젝트 형성하기

1) File>New>Java Project

2) 프로젝트 설정하기

프로젝트 설정하는 순서

[1] 프로젝트명 : 프로젝트가 저장될 상위 폴더
[2] JRE환경 설정 : 실행할 때, 어떤 JRE 버전 쓸 건지
[3] Project layout : 첫번째는 소스코드와 실행코드가 같은 폴더 내에 위치, 두번째는 각각 src/bin폴더 내에 위치한다.
[4] [Next] 선택 후 [Apply and Close]하여 완료

//.java와 .class 저장 위치 수정하려면 properties>Java Build Path>Source로 가면 된다.

[※ 참고 : 외부 또는 내부에서 이클립스로 프로젝트 가져오기]

이클립스 에디터 사용한 프로젝트 가져오기

1. New>import>Exsting Projects into Workspace

2. 경로 지정하여 가져오기

이클립스 에디터 사용하지 않은 프로젝트 가져오기
1. new>project>java project 설정하고, 폴더명 경로 지정하여 가져오기

※ 메모장으로 작성한 코드는, 가져올 경우 인코딩 타입에 따라서 한글이 깨질 수 있음. (원본 소스코드를 긁어 오는게 빠르다.)

 

라. 작업 시작하기 - 클래스를 생성하자.

1) New > Class

2) 내용 작성하고 완료하기

 

 

마. 컴파일 하고 실행하기 : .java에서 ctrl+s를 하면 컴파일도 알아서 해준다. 실행은 재생 버튼을 누르기

* 이클립스 에디터를 사용하면, 굳이 cmd에서 명령어를 안 써도 소스코드 작성 후 ctrl+s만 눌렀을 때 알아서 컴파일을 해준다.

[참고 : 알면 좋은 내용들]

이클립스 프로그램 언어 확인 및 변경([x]하단)
1. 확인 : properties 우측 아이콘에 마우스 올리기
2. 변경 : properties 아이콘 더블클릭 

이클립스 단축키
1. 폰트크기 : ctrl + shift + +/- 
2. 전체화면 : 클래스명 탭(ex.*Hello.java) 더블클릭 
3. 자동완성 : 코드요약 + ctrl + space (ex. "syso"작성 + ctrl + space = System.out.println();)
4. 주석지정 : 영역지정+ctrl+shift+/
5. 주석해제 : 영역지정+ctrl+shift+\ (역슬래시)
6. 코드정렬 : ctrl+shift+F
7. 한줄끝으로 가기 : [end]
8. 들여쓰기 : tab / 내어쓰기 : shift+tab
9. 클래스 내 변수 확인 : ctrl + 코드명
10. import 클래스위치 자동입력/삭제 : ctrl+shift+o
11. 도움말 보는 방법(JRE라이브러리 확인) : " "드래그 + F4
12. 변수명 쉽게 바꾸는 단축키 ctrl+1

이클립스 환경 설정하기
1. 폰트 글꼴 바꾸기 - 언어마다 글자 너비 다름
  [1] Colors and Fonts의 Text Edit 열기 
      : Window>Preferences>General>Apperance>Colors and Fonts>Basic>Text Font>[Edit]
  [2] 00체로 끝나는 글꼴로 설정 후 [확인] 선택
  [3] [Apply and Close]
2. 도구창 보고 끄기 : Windows>Show View

 

 

3. 자바의 동작 원리

 

(1) 소스와 프로그램이란?

    가. 소스(Source) : 원천, 원인이라는 의미

     = 기호, 부호라는 의미에서 코드로도 부름

     = 의미를 전달하는 약속이라는 의미로 언어로도 부름

    나. (Application) : 소스코드로 작성한 결과물

     = 프로그램

 

(2) 자바 소스가 프로그램으로서 동작하는 과정

JDK가 소스코드 컴파일링 -> JVM이 OS(ex.window)에 맞게 실행코드 실행 -> 컴퓨터 화면

※ 왜 자바는 컴퓨터공학에서 배운 C언어와 다르게 컴파일 후 컴퓨터로 바로 실행하지 않고, JVM을 사용해서 컴파일을 하고 실행을 할까?

-- 참조 : https://jaeseongdev.github.io/development/2021/03/08/%EC%9E%90%EB%B0%94%EC%9D%98_%EA%B0%80%EC%9E%A5_%ED%81%B0_%EC%9E%A5%EC%A0%90_%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C%EC%97%90_%EB%8F%85%EB%A6%BD%EC%A0%81%EC%9D%B4%EB%8B%A4/

 

자바의 가장 큰 장점 - 운영체제에 독립적이다.[WORA(Write Once, Run Anywhere)]

Java의 JVM WORA(Write Once Run Anywhere)에 대해서 알아보자. WORA라는 개념이 탄생하게 된 배경부터, 왜 JVM의 WORA가 혁신적인지 과거의 이야기부터 차근차근 살펴보자.

jaeseongdev.github.io

 

 

4. 자바의 특징

- 참조 : [JAVA의 정석], 남궁성 지음

(1) 운영체제에 독립적이다. 

: 자바 프로그램은 JVM을 통해서만 통신하여, 어느 운영체제이던 독립적이지만, 그만큼 운영체제에 종속적이다.

(2) 객체지향언어이다.

(3) 비교적 배우기 쉽다

(4) 자동 메모리 관리 

: 가비지 컬렉터가 있어 자동적으로 메모리를 관리해준다.

pf. C언어의 경우 포인터와 malloc을 통해 힙 메모리 공간을 할당한 후, free()하여 메모리 할당을 해제했다.

(5) 네트워크와 분산처리를 지원한다. 

(6) 멀티쓰레드를 지원한다.

(7) 동적 로딩을 지원한다.

: 여러개의 클래스로 되어 있어, 필요한 시점에 특정 클래스만 컴파일링 하거나 특정 클래스를 호출할 수 있다.

 

 

5. 자바로 만들 수 있는 것들

 

(1) JavaEE를 활용해 웹 작업 가능

(2) 안드로이드 앱 만들기

- android development document 를 구글에 검색해서 Android 프로젝트를 만드는 법을 읽자

- android studio 툴을 통해 앱을 쉽게 만들 수 있다.

- android studio 에서는 자바 언어 또는 코틀린을 통해 소스코드를 작성할 수 있음

(3) 하둡을 활용해 빅데이터 작업 가능

(4) 사물인터넷 (IoT, Inter of Things)

- 컴퓨터는 시대가 바뀌면서, FAST/CHEAP/SMALL 세가지 특성을 가지고 진화해왔다.

- 사물 인터넷은 전구, 커튼, 전동자전거 등에 내장된 진화된 작은 컴퓨터와 그를 제어하는 프로그램을 일컫는다.

- 라즈베리파이 : 교육용 소형 컴퓨터 

- 자바를 통해 사물인터넷 프로그램을 만들 수 있다.

 

 

 

[참조]

- 블로그 (링크는 위에 있음)

- [자바의 정석], 남궁성 지음

- 생활코딩, 부스트코스

- 그 외 국비지원과정 수업 내용 참조

1. 자바란?

- 1991년 제임스 고슬링에 의해 만들어진 객체 지향 프로그래밍 언어

- '한 번 작성하면 어디서든 실행된다'는 목표를 가지고 만들어졌다.

[※ 참고하기 객체지향과 절차지향이란?]

(1) 절차지향(PP, procedure programming) : 하나씩 절차에 따라 코드를 작성하는 것 (순서대로 쓰는)
    - 절차지향은 "순서"에 따라 "데이터"를 어떻게 입출력할 건지 고려하여 코드를 작성한다.
    - C언어의 경우, 절차지향언어로 잘 알려져 있는데, 
      C언어는 3세대 컴파일러 언어로, 한 번 컴파일을 하면 그 자체를 컴퓨터가 통으로 읽는다. 
      그렇기에 소스코드도 #include, 프로토타입을 선두에 먼저 쓰고, 차곡차곡 코드를 작성해준다.

(2) 객체지향(OOP, object oriented programming) : 객체(속성+기능)을 꺼내 쓰는 것(골라쓰는)
    - 객체지향은 절차지향과 다르게 속성과 기능들을 하나로 묶어서 객체로 만든다. 
    - 과거 우주항공이 발달되던 시절, 
      실제 세계는 여러 객체가 서로 상호작용하며, 
      각 객체 내에는 자신 고유의 속성과 기능이 존재한다는 것을 알고 객체지향언어를 만들어냈다.
   
(3) 절차지향언어와 객체지향언어는 대립된 관계가 아니다.
    - 자바를 쓰더라도 절차적으로 코드를 짤 수 있다.


2. JDK,JRE 설치하기(운영체제별로 상이)

 

[설치 순서 요약]

[1] 내 컴퓨터의 운영체제 사양 확인(32bit or 64bit)
[2] JDK, JRE 설치 (Oracle에서 JDK installer를 설치하면 JRE도 같이 설치된다)
[3] 시스템 환경변수 설정하기

 

(1) 내 컴퓨터의 운영체제 사양 확인(32bit or 64bit)

- 내 컴퓨터 > 내PC > (우측마우스) 속성

 

 

 

 

 

 

 

 

 

 

 

 

- 장치사양 > 시스템 종류 확인 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

(2) JDK, JRE 설치

- Oracle JDK 설치파일 다운로드 링크 : Oracle,  https://www.oracle.com/java/technologies/downloads/

- 위 링크는 영어다. 어려우니 페이지에서 설치파일 찾는법을 적어보았다.

  [0] java 버전을 먼저 고른다. - java 8, java 11, java 17....

     (현장에서는 java 8이 자주 쓰이므로 java8을 다운하는 것이 좋다 한다..) 

  [1] 운영체제 탭(Linux/macOS/Windows)에서 내 컴퓨터의 운영체제를 선택(ex. windows)한다.

  [2] 운영체제 크기(32bit or 64bit)에 따라 파일 다운로드 

      * Compressed Archive = 압축 버전

      * Installer = 설치 
        // 아래 이미지에 형광색 표시는 Compressed에 했는데, Installer로 설치하면 된다.

 

[ ※ 참조하기 : JDK,JRE,JVM은 뭐고, 왜 JDK는 운영체제마다 설치파일이 다를까? ]

(1) JDK,JRE,JVM이란?
- java언어는 '한 번 실행하면 어디서든 작동'되기 위해 만들어진 언어이다. 그렇기에 java언어 자체는 어느 운영체제이건 독립적으로 작동하는 것이 맞다. 
- JDK는 개발자를 위해 만들어진 개발용 키트다. 우린 JDK를 통해 컴파일을 할 수 있고, 개발툴을 사용할 수 있다.
- JRE는 자바 런타임 환경을 말하는 것으로, JDK를 설치할 때 같이 설치되며, 여러 라이브러리와 각종 파일을 담고 있다.
  (사용자용은 JRE만 별도로 설치 가능)
- JVM은 자바 가상 머신을 말하는 것으로, 이 JVM이 JDK의 심장이며, 프로그램을 운영체제에 맞게 실행하는 역할을 한다.
- JDK 설치파일이 운영체제마다 달랐던 이유는, 각 운영체제에 맞춰 이 jdk가 각각 조금씩 달랐기 때문이다.
  (쉽게 말해 이렇다. 초콜릿을 만들 때, 같은 카카오 재료(자바)를 쓰더라도, 중간에 어떤 공정과정(각 운영체제별 JDK)을 거치느냐에 따라 단짠이 좋은 이(Windows)에게 맞을 수 있고, 아니면 쌉쌀한 쓴맛이 좋은 이(Unix)에게 맞을 수도 있다.)
* 참고 이미지 출처 : https://codevang.tistory.com/86



(2) JDK/JRE의 JVM이 작동되는 과정
- 가정 : 개발자가 컴퓨터에서 프로그램 1,2,3...을 개발했다.

- 개발 중>
  JDK에서 각각의 프로그램에 대해 컴파일링
  **컴파일 시 문자의 인코딩도 함께 이루어진다.
  **java -encoding utf-8 hello.java : java언어로 작성한 소스코드의 문자를 jdk가 컴파일 시 UTF-8 형식으로 인코딩

- 실행 시>
  프로그램 1,2,3... 각각 실행 시, 컴퓨터 내 JRE에 따라서 JVM 1,2,3... 이 각각 형성되어 구동


(3) 운영체제에서 명령어를 작성해서 자바가 잘 설치되었는지 확인하는 방법

: java -version, javac -version 을 작성해서 자바가 잘 설치되었는지 확인 

 

3. 시스템 환경 설정하기

※ 참조 : https://whitegom.tistory.com/3

 

(1) [시스템 속성]에서 [환경변수]창 열기

- 환경 설정 접근 경로1 : 제어판>시스템및보안>시스템>고급시스템설정>고급>환경변수

- 환경 설정 접근 경로2 : 윈도우 탐색기 > "시스템 환경 변수 편집" 검색>고급>환경변수

 

(2) JAVA_HOME 변수값 만들기

[1] [새로 만들기]를 누르고 

[2] 변수명을 JAVA_HOME으로 한 뒤, java.exe와 javac.exe 위치의 상위 폴더 경로를 입력

[3] [확인]을 누른다.

[※ 여기서 잠깐! ~~~에 대한 사용자변수(U)와, 시스템 변수(S)는 뭘까?]
- 컴퓨터를 쓸 때, 같은 운영체제 내에서 사용자가 여러명이 있을 수 있다.
- 지금 여기에서의 특정 사용자를 위한 변수를 사용자변수라 하고, 모든 사용자를 위한 공통 변수를 시스템 변수라 한다.

 

(3) PATH에 자바 설치 위치 입력하기

[1] Path를 더블클릭
[2] java.exe와 javac.exe가 있는 폴더경로까지 입력 // %JAVA_HOME%\bin

 

 

4. 시스템 환경 설정이 잘 되었는지 확인하기

(1) JAVA_HOME 변수가 잘 입력되었는지 확인 -- 명령인자 echo 사용 (상세 경로 출력)

 

(2) path가 잘 설정되었는지 확인 -- path 입력 또는, java/javac입력

▼ cmd에 path를 입력하니, 아래와 같이 java.exe이 설치된 경로가 나타난다.

▼ cmd에 java를 입력하니, 아래와 같이 나온다.

   - path가 잘 설정되지 않으면, "내부 또는 외부 명령, 실행할 수 있는 프로그램, 또는 배치 파일이 아닙니다"가 뜬다.

 

 

5. 시스템 환경 설정에서 "클래스 환경 변수" 추가하기

(1) 클래스 환경 변수 --  CLASSPATH = .   //내 프로그램을 기준으로 다른 클래스를 참조하겠다.

     .  : 현재 경로
     .. : 상위 경로

 

[※ 참고하기 : cmd에서 위치 이동하는법 [cd] 사용]

경로를 이동해보자

     .  : 현재 경로
     .. : 상위 경로
     \ : 이 드라이브의 맨 앞
    cd : change directory

 

[※ 참고하기 : 시스템 환경 설정을 왜 해야할까?]

- cmd의 default 경로 : C드라이브>사용자(user)>현재사용자명

- JDK을 다운로드하면 보통 C드라이브>programe files>java에 파일들이 설치된다. 
- 그러나 앞서 말했듯 cmd의 default위치는 user명이고, 우리가 저장할 소스코드는 컴퓨터 내에 어디에든 있을 수 있다.
- 컴퓨터는 바보라, path 지정 없이는 컴파일하는 javac.exe나, 실행하는 java.exe의 위치를 명시해야 그게 뭔줄 알고 작업을 한다.
▼ path 설정을 안 하면, 아래처럼 "  "안에 javac.exe의 상위 경로를 모두 치고 + .java를 해야 컴파일이 된다.


- 이렇기 때문에, 컴퓨터의 어느 위치에 있더라도, java.exe와 javac.exe가 접근할 수 있게 구태여 path 설정을 해준 것이다.

 

 

+ Recent posts