/*
파일이름: Blockcomment.java
작 성 자: 홍길동
작 성 일: 2019년 7월 25일
목 적: System.out.println 메소드의 기능 테스트
*/
// 파일이름: LineComment.java
// 작 성 자: 홍길동
// 작 성 일: 2019년 7월 25일
// 목 적: System.out.println 메소드의 기능 테스트
class HelloWorld {
public static void main(String[] args) {
/* 다음은 단순한 정수의 출력*/
System.out.println(7);
System.out.println(3.15); // 다음은 단순한 정수의 출력
System.out.println("3+5="+8);
System.out.println(3.15+"는 실수입니다.");
System.out.println("3+5"+"의 연산 결과는 8입니다");
System.out.println(3+5);
/* 다음은 덧셈 결과의 출력 */
System.out.println("3"+5); // 덧셈 결과의 출력
}
}
class UseVariable {
public static void main(String[] args) {
double num1, num2; //두 개의 변수 동시 선언
double result;
num1=1.0000001;
num2=2.0000001;
result=num1+num2;
System.out.println(result);
}
}
----------------------------------------------------------------------
class OeratePromotion {
public static void main(String[] args) {
int num1 = 11;
int num2 = 22;
int result = num1 + num2;
System.out.println(result);
}
}
------------------------------------------------------------------------
public class CharTypeUnicode {
public static void main(String[] args) {
char ch1 = '헐';
char ch2 = '확';
char ch3 = 54736; // 문자 '헐'의 유니코드 값
char ch4 = 54869; // 문자 '확'의 유니코드 값
char ch5 = 0xD5D0;
char ch6 = 0xD655; // 0x뒤에를 16진수로 표현한 것
System.out.println(ch1 + "" + ch2);
System.out.println(ch3 + "" + ch4);
System.out.println(ch5 + "" + ch6);
}
}
-----------------------------------------------------------
public class Boolean {
public static void main(String[] args) {
boolean b1 = true;
boolean b2 = false;
System.out.println(b1); // b1이 지닌 값 출력
System.out.println(b2);
int num1 = 10;
int num2 = 20;
System.out.println(num1 < num2); // num2가 더 큰가?
System.out.println(num2 < num1); // 10 < 20 연산의 결과 출력
}
}
/*변수를 선언할 때 final 이라는 선언을 추가하면 그 변수는 '상수'가 된다
- 값을 딱 한 번만 할당할 수 있다 / 한 번 할당된 값은 변경이 불가능하다
*/
/* 상수의 이름은 모두 대문자로 짓는다.
* 이름이 둘 이상의 단어로 이뤄질 경우 단어 사이에 언더바를 넣는다.
*/
public class Constants {
public static void main(String[] args) {
final int MAX_SIZE = 100; // 상수 MAX_SIZE의 선언
// 보편적인 코드 : 상수를 선언과 동시에 초기화
final char CONST_CHAR = '상'; // 문자를 상수화시킴
final int CONST_ASSIGNED; // 초기화하지 않음 -> '딱 한 번' 초기화 허용(이 경우 오류x)
CONST_ASSIGNED = 12; // 할당하지 않았던 상수의 값 할당
System.out.println("상수1 : " + MAX_SIZE);
System.out.println("상수2 : " + CONST_CHAR);
System.out.println("상수3 : " + CONST_ASSIGNED);
}
}
--------------------------------------
/* 리터럴 -> 자료형을 기반으로 표현이 도는 상수를 의미한다
* ex) int num1 = 5 + 7;
* ex) double num2 = 3.394.5;
* 정수는 무조건 int형으로 인식하기로 약속
* 따라서 5와 7은 ' 정수형 리터럴 ' 이다.
* 그리고 3.3과 4.5는 '실수형 리터럴'이다 (double을 기반으로 저장이 된 후 연산이 이루어짐)
* '리터럴'이라는 표현은 '상수'라는 표현으로 대신하는 경우가 많다.
* 8진수로 int형 정수 표현 : 숫자 앞에 0 삽입 -> int num = 011 + 022 + 033;
* 16진수로 int형 정수 표현 : 숫자 앞에 0x또는 0X 삽입 -> int num = 0x11 + 0x22 + 0x33;
*/
public class IntegerLiterals {
public static void main(String[] args) {
int num1 = 123; // 10 진수 표현 1*3 + 10*2 + 100*1 ->2
int num2 = 0123; // 8 진수 표현 1*3 + 8*2 + 64*1 ->83
int num3 = 0x123; // 16 진수 표현 -> 어떻게 표현하느냐는 코드상에서만 의미(실행하면 10진수로 출력)
// 1*3 + 16*2 + 256*1 -> 291
System.out.println("num1: " + num1);
System.out.println("num2: " + num2);
System.out.println("num3: " + num3);
System.out.println("11 + 22 + 33 = " + (11 + 22 + 33));
System.out.println("011 + 022 + 033 = "+ (011 + 022 + 033));
// 9 + 18 + 27
System.out.println("0x11 + 0x22 + 0x33 = " + (0x11 + 0x22 + 0x33));
// 17 + 34 + 51
}
}
/* 다음과 같은 연산을 byte형 / short형으로 정수를 표현하는 방법을 제공하지 않는다.
그래서 아래 같은 경우 허용!
(long형은 별도 -> l 또는 L을 붙여서 long형 상수로 표현해달라는 요청 해야함)
byte num1 = 5;
short num2 = 25;
-이진수 표현법 OB or ob
ex) byte seven = 0B111;
ex) int num205 = 0B11001101;
단위가 큰 수의 표현 및 인식 -> 중간에 언더바
ex) int num = 100_000_000;
*실수형 상수
System.out.println(3.004999D + 2.0004999D);
D는 붙이나마나 기본적인 것! 거의 안 씀
System.out.println(3.0004999f + 2.0004999f);
메모리 공간은 적게 쓰겠지만 오타의 크기는 더욱 커질 것
*3.4e3 - > 3.4 * 10의3승 = 3400.0
3.4*e3라고 생각하고 e옆의 숫자를 10의 지수로 올림! */
----------------------------------------
/*이스케이프 시퀀스(escape sequences)
-> 유니코드 문자들 중 키보드로 입력하기 어려운 문자의 표현을 위한 것
화면상의 어떠한 상황 또는 상태를 표현하기 위해 약속된 문자
* '\b' - 백스페이스 문자
* '\t' - 탭 문자
* '\\' - 백슬래시 문자
* '\'' - 작은따옴표 문자
* '\"' - 큰따옴표 문자
* '\n' - 개 행 문자
* '\r' - 캐리지 리턴 문자
*/
public class EscapeSequences {
public static void main(String[] args) {
System.out.println("AB" + '\b' + 'C'); //AB먼저 출력 ->백슬래시로 B지워지고 C가 들어옴
System.out.println("AB" + '\t' + 'C'); // 탭
System.out.println("AB" + '\n' + 'C'); //개행
System.out.println("AB" + '\r' + 'C'); // AB출력 -> 커서를 왼쪽 끝으로 이동 후 A가 지워지고 C가 들어옴
}
}
-------------------------------------------
public class UnicodeEscapes {
public static void main(String[] args) {
System.out.println("오늘의 환율은 1$dp 0.88 " + '\u20AC' + "입니다.");
}
}
/* 형 변환 - > 자동형변환 or 명시적형변환(강제형변환)
ex) short n1 = 10;
short n2 = 20;
int n3 = n1 + n2; (short -> int로 변환) 출력 잘 된다!
But / long형일 경우 > 8byte -> 4byte 데이터 손실이 발생!(다른 정수들은 int형으로 변환되어서 진행)
int형 정수의 덧셈 방법과 double형 실수의 덧셈 방법은 다르다. -> 데이터 표현 방법에 따라 덧셈 방법도 달라짐
(자료형이 다른 두 값을 대상으로는 덧셈을 진행하지 못한다.)
int num1 = 50;
long num2 = 3147483647L;
System.out.println(num1 + num2) // num1과 num2의 자료형이 다르다. -
두 피연산자의 자료형이 일치해야 동일한 방법을 적용하여 연산을 진행할 수 있다.
피연산자의 자료형이 일치하지 않을 때 형의 변환을 통해 일치를 시켜야 한다.
->num1에 저장된 값이 long형으로 형변환된다.(자동형변환)
*이 경우엔 int형 변수에 담긴 값을 long형으로 변환하여 메모리에 임시 저장한다
*이어서 이 변환된 값과 num2에 저장된 값을 대상으로 덧셈을 진행한다
-> 이러한 일련의 과정을 가리켜 '자료형 변환' 또는 '형 변환'이라 한다
*자동형변환
규칙 1 : 자료형의 크기가 큰 방향으로 형 변환이 일어난다.
규칙 2 : 자료형의 크기에 상관없이 정수 자료형보다 실수 자료형이 우선한다(정수 자료형일때도 byte가 큰 것이 우선)
*정수형 데이터를 실수형으로 변환하면 데이터의 손실은 발생하지 않는다.
[byte]->[short / char]->[int]->[long]->[float]->[double]
*화살표 방향이 표시하는 쪽으로 형 변환이 가능! (자동 형 변환)
ex) double num1 = 30; // int형 정수 30은 double형으로 자동 형 변환
ex) System.out.println(59ㅣ + 34.5); // long형 정수 59은 double형으로 자동 형 변환
(double -> long 으로는 형변환 불가능)
*명시적 형 변환(Explicit Coversion) ex) double형 데이터를 long형 데이터로 바꿔야하는 경우
ex) double pi = 3.1415; // 정수 '3'만 저장
int wholeNumber = (int)pi; // pi의 값을 int형으로 명시적 형 변환
()에 내가 변환하고 싶은 자료형의 이름 써 줌!
ex) long num1 = 30000007L;
int num2 = (int)num1; // num1의 값을 int로 명시적 형 변환
long형 -> int형 변환 -> 상위 바이트가 잘려나감
******
short num1 = 1;
short num2 = 2;
short num3 = sum1 + num2; // 컴파일 오류 발생
short인데 연산을 해야하니까 1,2는 int형으로 바뀜
'int1 / int2'가 되어 덧셈이 진행되게 되는데 그러면 int형 결과 3이 나옴
short num3에 넣을 수 x
-->>> short num3 = (short)(num1 + num2); 이렇게 !
*이 중 형 변환에 사용된 소괄호 - 연산자
*묶거나 구분하는 목적으로 사용되는 소괄호 - 구분자 */
// 대입 연산자 & 산술 연산자 - =,+,-,*,/,%
public class ArithOp {
public static void main(String[] args) {
int num1 = 7;
int num2 = 3;
System.out.println("num1 + num2 = " + (num1 + num2));
System.out.println("num1 - num2 = " + (num1 - num2));
System.out.println("num1 * num2 = " + (num1 * num2));
System.out.println("num1 / num2 = " + (num1 / num2));
System.out.println("num1 % num2 = " + (num1 % num2));
}
}
/*피 연산자가 둘인 연산자 - '이항 연산자'
/ - 몫 반환
% - 나머지 반환
cf. System.out.println("num1 / num2 = " + (7.0 / 3.0);
-> 결과도 double으로 나온다 ! (실수형 나눗셈 진행)
-> num1 / num2 = 2.333333333333335 (이케 나옴)
*/
----------------------------------------------------------------------
public class BitOperator {
public static void main(String[] args) {
byte n1 = 5; // 00000101
byte n2 = 3; // 00000011
byte n3 = -1; // 11111111 (00000001 -> 11111110 -> 11111111)
byte r1 = (byte)(n1 & n2); // 00000001 (and)
byte r2 = (byte)(n1 | n2); // 00000111 (or) 둘 중 하나라도 1이면 1
byte r3 = (byte)(n1 ^ n2); // 00000110 두개가 달라야 1
byte r4 = (byte)(~n3); // 00000000 비트 싹 바꿔줌 (익스클로씨브?)
System.out.println(r1); // 00000001은 1
System.out.println(r2); // 00000111은 7
System.out.println(r3); // 00000110은 6
System.out.println(r4); // 00000000은 0
}
}
--------------------------------------------------------------------------------
/* 비트를 대상으로 하는 연산자들 (반드시 정수!)
* & : 비트 단위로 AND 연산을 한다 -> (두 비트가 모두 1 일 떄 1을 반환)
* | : 비트 단위로 OR 연산을 한다 -> (두 비트 중 하나라도 1이면 1을 반환)
* ^ : 비트 단위로 XOR 연산을 한다 -> (두 비트의 값이 서로 다른 경우에 1을 반환)
* ~ : 피연산자의 모든 비트를 반전시켜서 얻은 결과를 반환 ex) ~n; (byte의 not. 틸트?)
* cf) 논리 not : !
*/
public class BitOpMeans {
public static void main(String[] args) {
byte n1 = 13;
byte n2 = 7;
byte n3 = (byte)(n1 & n2); // 비트 연산 &의 결과는 int형 -> 형 변환 필요
System.out.println(n3);
/* n1 : 0 0 0 0 1 1 0 1 (13)
n2 : 0 0 0 0 0 1 1 1 (7)
-> n3 : 0 0 0 0 0 1 0 1 (5)
*비트 연산자는 각각의 비트를 대상으로 연산을 진행한다.
*그리고 각 비트를 대상으로 진행된 연산 결과를 묶어서 하나의 연산 결과를 반환한다.
*/
}
}
-
-----------------------------------------------------
/* 비트 쉬프트(Shift) 연산자 : << , >> , >>> (정수만 가능)
* << : 피연산자의 비트 열을 왼쪽으로 이동 / 이동에 따른 빈 공간은 0으로 채움
* >> : 이동에 따른 빈 공간은 음수의 경우 1,양수의 경우 0으로 채움
* >>> : 이동에 따른 빈 공간은 0으로 채움 (부호비트 상관x)
*/
public class BitShiftOp {
public static void main(String[] args) {
byte num;
num = 2; // 00000010 (빈공간 0으로 채워짐)
System.out.print((byte)(num << 1 ) + " "); // 00000100
System.out.print((byte)(num << 2 ) + " "); // 00001000
System.out.print((byte)(num << 3 ) + " " + '\n'); // 00010000
num = 8; // 00001000 (부호 비트에 따라서 빈공간 채워짐)
System.out.print((byte)(num >> 1) + " "); // 00000100
System.out.print((byte)(num >> 2) + " "); // 00000010
System.out.print((byte)(num >> 3) + " " + '\n'); // 00000001
// -1 : 11111111 , -2 : 11111110
num = -8; // 11111000 (부호 비트 유지해서 빈공간이 1로 채워짐!)
System.out.print((byte)(num >> 1) + " "); // 11111100
System.out.print((byte)(num >> 2) + " "); // 11111110
System.out.print((byte)(num >> 3) + " "); // 11111111
}
}
// 왼쪽을의 쉬프트는 값의 2배 증가 / 오른쪽으로의 쉬프트는 값을 2배 나눈 결과로 이어진다.
-------------------------------------------------------------
public class CompAssignOp {
public static void main(String[] args) {
short num = 10;
num = (short)(num + 77L); // 형 변환 안하면 컴파일 오류 발생,
// long형 데이터를 short형에 저장할 수 x -> 강제형변환 해줌 -> 에러
int rate = 3;
rate = (int)(rate * 3.5); // 형 변환 안하면 컴파일 오류 발생
System.out.println(num);
System.out.println(rate);
// int형으로 바꿔줬으니까 10이 나온다 !
num = 10;
num += 77L; // 형 변환 필요하지 않다.
// 복합 대입 연산자를 사용할 경우 '강제형변환'을 해주지 않아도 알아서 처리해준다! ( 주의 필요)
rate = 3;
rate *= 3.5; // 형 변환 필요하지 않다.
// 가급적이면 이러한 형태로 표현 잘 안한다.
System.out.println(num);
System.out.println(rate);
}
}
// 코드 구성 자체로 볼 때 첫번째처럼 해주는게 더 의미가 있음 !
-------------------------------------------------------------
/* 논리연산자 : &&, ||, ! -> true 아니면 false 를 반환하는 연산 옴 -> true / false 나옴
* A && B - A와 B 모두 true면 연산 결과는 true (논리 AND) ->
* A || B - A와 B 둘 중 하나라도 true이면 연산 결과는 true (논리 OR) ->
* !A - 연산 결과는 A가 true이면 false, A가 false이면 true (논리 NOT) <-
* 논리 연산자의 연산 결과를 나타낸 표 - > 진리표
*/
public class LogicalOp {
public static void main(String[] args) {
int num1 = 11;
int num2 = 22;
boolean result; // boolean - 참거짓
// 변수 num1에 저장된 값이 1과 100 사이의 수인가?
result = (1 < num1) && (num1 < 100);
System.out.println("1 초과 100 미만인가?" + result);
//변수 num2에 저장된 값이 2 또는 3의 배수인가?
result = ((num2 % 2) == 0) || ((num2 & 3) == 0);
System.out.println("2 또는 3의 배수인가? " + result);
// 변수 num1이 0인가?
result = !(num1 !=0); // num1이 0이 아니냐? -> true-> !붙어서 false 반환
System.out.println("0 인가? " + result);
}
}
/* num = 2 + 3 -> '덧셈 연산 후 5가 저장이 된다'라고 생각하는 것 보다
num = 5 <-------2와 3을 더한 결과가 이 자리를 대체한다고 생각하기' -> 반환된다 ! */
--------------------------------------------------------------
public class PostfixOp {
public static void main(String[] args) {
int num = 5;
System.out.print((num++) + " "); // 출력 후에 값이 증가
// 원래 자기가 가지고 있던 '5'라는 값을 남기고 이 연산을 끝맺음
System.out.print((num++) + " "); // 출력 후에 값이 증가
System.out.print(num + "\n");
System.out.print((num--) + " "); // 출력 후에 값이 감소
System.out.print((num--) + " "); // 출력 후에 값이 감소
System.out.print(num);
}
}
--------------------------------------------------------
/* 증가 및 감소 연산자 : prefix ++ / prefix --
++ 변수 ++ (둘 다 똑같이 '1' 증가)
앞 -> 일단 먼저 증가를 시킨 후 변수에 저장된 값을 활용해라.
뒤 -> 변수에 저장된 값을 먼저 활용한 후 나중에 증가를 시켜라.
*/
public class PrefixOp {
public static void main(String[] args) {
int num = 7;
System.out.println(++num); // num의 값 하나 증가 후 출력
System.out.println(++num); // num의 값 하나 증가 후 출력
System.out.println(num);
}
}
/* 1. val = ++n -> n의 지정된 값이 5라고 가정 -> 6으로 바뀜(증가된 값이 반환)
val = 6;으로 마지막으로 대입연산을 진행하게 된다.(실제 val에 저장되는 값은 6)
2. val = n++ -> n 값을 증가시키기 이전에 n이 가지고 있는 값은 문장에서 활용하라.
일단은 값이 증가가 됐다고 가정 후 연산을 대체할 때
즉, 결과를 내놓을 때 증가되기 이전값을 마지막으로 한 번 내놓고 다음 문장으로 넘어가겠단 의미
-> 뒤에 ++이 붙으면 값의 증감은 다음 문장으로 넘어가야 반영이 된다 !
*/
----------------------------------------------------
/*관계 연산자(비교 연산자) - < , > , <= , >= , == , != --> true / false 반환
* n1 !=n2 (n1과 n2가 다른가?)
*/
public class RelationalOp {
public static void main(String[] args) {
System.out.println("3 >= 2 : " + (3 >= 2));
System.out.println("3 <= 2 : " + (3 <= 2));
System.out.println("7.0 == 7 : " + (7.0 == 7));
System.out.println("7.0 != 7 : " + (7.0 != 7));
}
}
/* 7.0 == 7 : true -> false가 나올수도! 7.0이라고 쓰는 순간 '오차'가 존재하게 되기 때문!
비교해도 같을 수 없는데 비교를 하려면 두 수의 자료형을 일치 시킨 후 비교 연산 진행*/
----------------------------------------------------------
/* SCE(Short-Circuit Evaluation) :'연산의 효율 및 속도를 높이기 위해서 불필요한 연산을 생략하는 행위'
- &&의 왼쪽 피연산자가 false이면, 오른쪽 피연산자는 확인하지 않는다.
- ||의 왼쪽 피연산자가 true이면, 오른쪽 피연산자는 확인하지 않는다.*/
public class SCE {
public static void main(String[] args) {
int num1 = 0;
int num2 = 0;
boolean result;
// num1과 num2의 값이 모두 증가할 수 있을까?
result = ((num1 += 10) < 0) && ((num2 += 10) > 0);
System.out.println("result = " + result);
System.out.println("num1 = " + num1);
System.out.println("num2 = " + num2 + '\n'); // '\n'은 개행
result = ((num1 += 10) > 0) || ((num2 += 10) > 0);
System.out.println("result = " + result);
System.out.println("num1 = " + num1);
System.out.println("num2 = " + num2);
}
}
/* SCE에 의해 앞에만 계산되고 뒤에는 무시된다! (왼편에 있는 연산이 먼저 진행)
((num1 += 10) < 0) && ((num2 += 10) 10 > 0)
--> false && ((num2 += 10) > 0);
오른편에 있는 연산을 진행할 차례에서 이미 왼쪽이 false가왔으니 오른편에 무엇이 오든 &&의 연산 결과는 false
오른편 연산을 진행하지 않고 false반환 -> 결국 num2의 값은 증가하지 않는다. 따로따로 해서 코드 수정해야함!
num1 += 10;
num2 += 10;
result = (num1 < 0) && (num2 > 0)
-> 이것까지 고려해서 문장을 구성하자x , SCE가 발생할 수 있는 환경에서 생략되거나 생략되지 않을 수 있는
연산이 있다면 이렇게 문장을 작성하지 말자!
하나의 문장에 너무 많은 것을 담고 있으면 좋지 않은 표현! */
------------------------------------------------------------------------
public class UnaryAddMin {
public static void main(String[] args) {
short num1 = 5;
System.out.println(+num1); //결과적으로 불필요한 + 연산
System.out.println(-num1); // 부호를 바꿔서 얻은 결과를 출력
short num2 = 7;
short num3 = (short)(+num2); //형 변환 하지 않으면 오류 발생
short num4 = (short)(-num2); //형 변환 하지 않으면 오류 발생
System.out.println(num3);
System.out.println(num4);
}
}
/* short S1 = 2
short S2 = +S1 (short형 2가 int형 2가 된다!)
-> 형 변환이 생기면서 컴파일 오류 발생! -> 완성을 시키려면 short형의 형 변환을 해줘야한다!
* Continue : '위에서 부터 계속' (조건 검사) -> 빠져나가는거랑 상관x
둘 다 실행 흐름의 조절을 목적으로 반복문 내에 삽입되는 키워드
*/
public class BreakBasic {
public static void main(String[] args) {
int num = 1;
boolean search = false; // 왜 false 로 선언을 해놓은거지 ? true로 해도 값은 똑같이 나오는데 둘 중 아무거나 해도 상관이 없는건가?
// if문에 있는 조건이랑 반대로 선언 / 밖 false -> if문 true 이런식으로 !
//처음 만나는 5의 배수이자 7의 배수인 수를 찾는 반복문 - > 찾는 순간 while문은 자기 할 일 끝났으니 빠짐
while(num < 100) {
if(((num % 5) == 0) && ((num % 7) == 0)) {
search = true;
break; // while문을 탈출 (x가 20이면 break문을 실행하라!) 자기를 감싸고 있는 반복문을 빠져나감 !(if문이라고 생각하지않기)
}
num++;
}
if(search)
System.out.println("찾는 정수 : " + num);
else
System.out.println("5의 배수이자 7의 배수인 수를 찾지 못했습니다.");
}
}
/* break문을 감싸고 있는 것은 if문인데여?
-> 맞지만 break문이 실행되면 가장 근접한 거리에서 자신을 감싸고 있는 반복문을 찾아서 해당 반복문을 빠져나간다.
그리고 이어서 그 다음 문장을 실행하게 된다. */
-----------------
public class BreakPoint {
public static void main(String[] args) {
for(int i = 1; i < 10; i++) {
for(int j = 1; j < 10; j++) {
if((i * j) == 72) {
System.out.println(i + " x " + j + " = " + i*j);
break; // 안쪽 for문만 탈출
}
}
}
}
}
/* 위 예제에서는 곱의 결과가 72일 때 break문 실행
그러나 탈출하는 것은 안쪽 for문임! 즉, 바깥쪽 for문은 계속 실행.
8*9에서 끝나지 않고 9*8까지 실행 된 것을 볼 수 있음. 바깥쪽 for문까지 탈출하려면 어떻게 해야하는지는 다음 예시 ! */
---------------------
// 가장 쉬운 예 : 구구단
public class ByTime {
public static void main(String[] args) {
for(int i = 2; i < 10; i++) { // 2단부터 9단까지 진행 위한 바깥쪽 for문
for(int j = 1; j < 10; j++) // 1부터 9까지의 곱을 위한 안쪽 for문
System.out.println(i + "x" + j + "=" + (i*j));
}
}
}
-----------------------
/* 실행결과는 동일하지만 for문 중첩보다 코드 구성이 복잡! for문을 우선적으로 고려하기 !
*/
public class ByTimesWhile {
public static void main(String[] args) {
int i = 2;
int j;
while(i < 10) {
j = 1;
while(j < 10) {
System.out.println(i + " x " + j + " = " + (i * j));
j++;
}
i++;
}
}
}
--------------------------------
public class CondOp {
public static void main(String[] args) {
int num1 = 50;
int num2 = 100;
int big;
int diff;
big = (num1 > num2) ? num1 : num2;
System.out.println("큰 수 : " + big);
diff = (num1 > num2) ? (num1 - num2) : (num2 - num1);
System.out.println("절댓값 : " + diff);
// 값이 와야 할 자리에 연산이 올 수도 있음 ( 덧셈 / 뺄셈 등)
}
}
/* 조건(true or false연산) ? 수1(true일 경우 반환) : 수2(false일 경우 반환) */
---------------------------
00000000000000000000000
/* continue문은 반복문의 탈출과 거리가 멀다.
실행하던 반복문의 나머지 부분을 '생략'하고 프로그램의 흐름을 조건 검사 부분으로 이동한다.
while(n < 100) {
if(x == 20)
continue;
}
-> '위에서부터 계속해라!'
false가 된다 하면 continue문의 실행이 안되니까 무수히 많은 문장을 실행을 하고나서 또 다시 조건 검사 위로 올라감.
continue문이 실행이 된다면? -> 무수히 많은 문장들 '생략'!
그리고 다시 위로 올라가서 조건 검사부터 '다시 시작'
(단 do ~ while문의 경우 조건 검사가 위치한 맨 아래로 이동한다.)
아래 예제는 continue문이 활용되는 전형적인 모델
*/
// 100이하의 자연수 중에서 5의 배수이자 7의 배수인 정수를 전부 출력하고, 그 수를 세어서 출력하는 프로그램
public class ContinueBasic {
public static void main(String[] args) {
int num = 0;
int count = 0;
while((num++) < 100) { //1을 가지고 흐름을 타기 시작
if(((num % 5) != 0) || ((num % 7) != 0))
continue; // 5와 7의 배수 아니라면 나머지 건너뛰고 위로 이동 -> 아니면 continue문을 실행!
count++; // 5와 7의 배수인 경우만 실행
System.out.println(num); // 5와 7의 배수인 경우만 실행
}
System.out.println("count : " + count);
}
}
/* while문과 유일한 차이 : '조건 검사가 어디에 있느냐'
* while문 -> 무조건 조건이 만족되어야 실행을 하겠다. (선 검사)
* do ~ while문 -> 조건의 만족 여부에는 상관없이 일단은 한 번 실행을 하고 시작하겠다. (후 검사)
1. 중괄호 영역 실행 - > 2. 조건 검사 후 결과가 true이면 반복 결정
*/
public class DowhileBasic {
public static void main(String[] args) {
int num = 0;
do {
System.out.println("I like Java " + num);
num++;
} while(num < 5);
}
}
/* 결과
I like Java 0 -> 일단 0을 먼저 실행!
I like Java 1 -> 1이 된 상태로 반복 조건 검사 !
I like Java 2
I like Java 3
I like Java 4
while문으로 작성된 문장은 do ~ while문으로도 작성 가능하고 또 그 반대가 가능한 경우도 대부분.
다음에 같은 경우에 한해 do ~ while문 사용
" 조건에 따른 반복이 필요하다. 그런데 반드시 한 번은 실행을 해야 한다."
이외의 경우 while문 또는 for문을 사용하는 것이 바람직 ( 그래야 선택하는 반복문에 더 많은 의미 부여 가능 ) */
// while문과 비교 ; 조건들을 나란히 놓을 수 있게 한 것이 for문!
public class ForBasic {
public static void main(String[] args) {
for(int i = 0; i < 5; i++) // '반복'에 필요한 모든 것을 한 줄에 나열할 수 있음.
System.out.println("I love Java " + i); // i변수가 값이 변환되는 흐름까지 추적해야함!
}
}
/* while문과 for문의 각 구성들의 의미
* [int num] = 0; -> 반복의 횟수를 세기 위한 변수( 반복을 위한 변수 )
* [num < 5] -> ( 조건 만족 여부를 따지기 위함 )
* [num ++] -> 반복의 조건을 무너뜨리기 위한 연산 ( count를 증가시키기 위한 연산 )
위 긤에서 보인 for문에 처음 진입해서 첫 번째 실행이(첫 번째 루프가) 완료되기까지의 과정을 정리하면
1. 변수의 선언 및 초기화
2. 반복 조건이 true인지 확인
3. 반복 영역을 실행 ( 반복 조건이 true이면 )
4. 변수의 값 증가
그리다 반복 조건이 false가 되면, for문을 빠져나오면서 반복은 종료가 된다. */
/* 예제 하나 주구장창 파기 !
* 하나의 반복문 안에 다른 반복문이 삽입 된 경우 : '반복문의 중첩'
* for문을 가장 많이 사용하는 이유 : 몇 번 반복하는지, 언제까지 반복하는지 한 줄 딱 보면 나옴 !
* while ~ while 중첩 잘 안하는 이유 : 반복의 조건이 깨질 수 있는 상황과 변수가 위 & 중간 & 끝 - > 엄청 나뉘어짐 !
*/
public class ForInFor {
public static void main(String[] args) {
for(int i = 0; i < 3; i++) { // 바깥쪽 for문
System.out.println("--------------------");
for(int j = 0; j < 4; j++) { // 안쪽 for문
System.out.print("[" + i + "," + j + "]");
}
System.out.print('\n');
}
}
}
---------------
public class IEBasic {
public static void main(String[] args) {
int n1 = 5;
int n2 = 7;
// if문 (true or false 반환하는 연산 자리)
if(n1 < n2) {
System.out.println("n1 < n2 is true"); // n1 < n2 이면 실행되는 문장
// if ~ else 문
if(n1 == n2) {
System.out.println("n1 == n2 is true");
}
else {
System.out.println("n1 == n2 is false");
}
}
}
}
/* if문 / if ~ else문은 라인의 수에 상관없이 하나의 문장으로 자바 컴파일러가 인식
* if문에 속한 문장이 하나일 경우 중괄호 생략 가능 -> 습관이 되도록 연습
-> if(n1 < n2)
System.out.println("n1 < n2 is true");
else
System.out.println("n1 == n2 is false");*/
------------------------
public class IEIE {
public static void main(String[] args) {
int num = 120;
if(num < 0) // 먼저 검사
System.out.println("0 미만");
else if(num < 100) // 위 조건이 만족되지 않으면 여기서 다시 검사
System.out.println("0 이상 100 미만");
/* else {
if(num < 100)
System.out.println("0 이상 100 미만");
이렇게도 쓸 수 있지만 한 줄에 쓴 게 더 보기 좋음! */
else // 아무것도 만족되지 않으면 else에 속한 문장 실행
System.out.println("100 이상");
/* 조건에 따라 실행할 문장이 하나이기에 중괄호를 생략
* if ~ else if ~ else 문은 if ~ else문을 중첩시킨 결과이다.
* 이 코드는 if ~ else문의 절에 다른 if ~ else문이 존재하는 구조
* if ~ else문은 여러 줄에 걸쳐 있어도 하나의 문장
* if ~ else if ~ else문을 별도의 문장으로 인식하고 코드를 작성해도 문제가 되지 않는다.
*/
}
}
-----------------------
/* 반복의 조건이 true로 명시되어서 해당 반복문을 빠져나가지 못하도록 구성된 반복문 -> '무한 루프'
*while(true) { -> 무조건 계속 돌겠다는 것 !
의도적일수도 있지만, 어떤 특정 조건이 주어졌을 때 빠져나가도록 루프를 구성해야 함 ! (위 경우는 break문)
*do ~ while 무한 루프
do { ''''
} while(true)
* for( ; ; ) { -> 이렇게 비워놔도 무한 루프가 형성 된다 !
}
*/
// 6의 배수이면서 14의 배수인 자연수를 찾을 때까지 이 '반복'을 계속하겠다. -> 이 자연수를 찾기 위해 '값의 범위'를 제한하지 않기 위해 무한 루프 형성
public class InfinityLoop {
public static void main(String[] args) {
int num = 1;
while(true) {
if(((num % 6) == 0) && ((num % 14) == 0))
break; // 예측 : 어느 순간 if문의 조건이 참이 되어서 break문으로 빠져나와 실행이 될 수 있겠구나 !
num++;
}
System.out.println(num);
}
}
public class LabeledBreakPoint {
public static void main(String[] args) {
outer: for(int i = 1; i < 10; i++) { // 바깥쪽 for문에 레이블 outer 명시 !
for(int j = 1; j < 10; j++) {
if((i*j) == 72) {
System.out.println(i + " x " + j + " = " + (i*j));
break outer; // outer로 명시된 반복문까지 빠져나간다 !
}
}
}
}
}
// break문에 사용되는 레이블도 위치의 지정이 목적. 들여쓰기에 상관없이 잘 보이는 위치에 놓아두면 된다.
--------------------
public class SwitchBreak {
public static void main(String[] args) {
int n = 3;
switch(n) {
case 1:
System.out.println("Simple Java");
break;
case 2:
System.out.println("Funny Java");
break;
case 3: // case 3 영역 실행(여기 여러개 문장 넣을 수도 있음)
System.out.println("Fantastic Java");
break;
default :
System.out.println("The best programming language");
}
System.out.println("Do you like Java"); // switch문 빠져나와서 다음 문장 실행
}
}
/* 둘 이상의 레이블을 이어서 둘 수도 있다. <switch + break 구성의 다른 예>
switch(n) {
case 1 :
case 2 : ( 한 페이지에 여러개의 레이블을 붙여놓은 것과 같다.)
case 3 :
System.out.println("case 1,2,3");
-> case 1,2,3 어떤 것이 전달이 되던 실행위치는 여기부터 실행
(케이스 별로 나눌때는 유용 -> case3,4 이런 경우)
break;
default:
System.out.println("default"); */
-------------------------
public class SwitchVBasic {
public static void main(String[] args) {
int n = 3;
switch(n) { // switch 문에서는 중괄호가 당연히 들어간다고 생각하기 !
case 1:
System.out.println("simple Java");
case 2:
System.out.println("Funny Java");
case 3:
System.out.println("Fantastic Java");
default: // 내가 원하는 위치 찾지 못하면 default에서 실행
System.out.println("The best programming language");
}
System.out.println("Do you like Java?"); // 스위치문 밖 문장 실행
}
}
/* else if가 많이 들어가는 상황에서는 switch문이 더 좋은 선택이 될 수 있음
* switch : switch / case / default 로 구성
-> case와 default를 가리켜 '레이블(Label 라벨) 이라 한다.
-> 코드상에서 위치를 표시하기 위해 사용
JVM에게 이 위치에 내가 레이블 붙여놨어 ! 라는 의미로 사용
* case와 default눈 들여쓰기를 하지 않는다 -> 밖으로 튀어나와야만 레이블의 역할 가능 !
-> switch(n) {
case 1 : ~~ (x)
switch(n 어디서부터 실행을 할 것인지 결정) {
case 1 : n이 1이면 여기부터 실행
case 2 : n이 2이면 여기부터 실행
case 3 : n이 3이면 여기부터 실행
default : 해당하는 case 없으면 여기서부터 실행
}
(n = 2일 경우 case2로 이동해서 밑으로 쭉 실행 !
그 위에 case와 switch의 레이블들은 의미가 없어지고 2부터 쭉 실행)
이후 switch문 밖 문장 실행 */
-----------------------------------
// 앞 문장들은 코드의 '선택적 실행'을 위한 것들이지만, 지금부터는 코드의 '반복적 실행'을 위한 것들
public class WhileBasic {
public static void main(String[] args) {
int num = 0;
// 반복할 영역을 중괄호 안에 넣는다 ( 하나면 생략 가능 )
while(num < 5) { // num < 5 을 만족하면 반복 실행 , 조건 만족 안하면 문장 실행 안하고 빠져나갈수도 !
System.out.println("I like Java " + num); //이 조건이 만족하지 않을 때까지 반복
num++; // 없으면 반복문 빠져나오지 못함
}
}
}
/* while(반복 조건)
System.out.println("I like Java" + num) -> 반복
num++; -> 영역
--> true를 반한하는 동안에는 횟수에 상관없이 while문의 중괄호가 반복 실행
(처음부터 false가 반환되면 while문의 중괄호는 한 번도 실행되지 않을 수 있다.)
* 먼저 ! 조건 검사 -> 그리고 결과가 true이면 중괄호 영역 실행 */*/
재귀 안함
/* <키워드 return문이 지니는 두 가지 의미> : return문이 실행되면 메소드가 종료되면서 값이 반환된다.
* 1) 메소드를 호출한 영역으로 값을 반환 -> return문 오른쪽에 오는 값을 변환
* 2) 메소드의 종료
가 동시에 만들어지는데 사정상 메소드를 종료해야 하는 경우 아래 예시 */
public class OnlyExitReturn {
public static void main(String[] args) {
divide(4, 2);
divide(6, 2);
divide(9, 0);
}
// divide(나눗셈) -> num1 / num2 (분모는 '0'이 될 수 x) ~> 실행과정 중간에 종료가 돼버림!
public static void divide(int num1, int num2) {
if(num2 == 0) {
System.out.println("0으로 나눌 수 없습니다.");
return; // 값의 반환 없이 메소드만 종료 -> 중간에도 올 수 있음 !
// 값은 반환하지 않지만 메소드의 '종료'라는 효과는 그대로 반영!
}
System.out.println("나눗셈 결과 : " + (num1 / num2));
}
}
/* 계산이 안되니까 계산된 거 하나도 없어도 종료하고 싶은 경우
-> 어떤 조건이 만족이 돼서 반환해야 할 값들이 이미 계산결과가 끝남
-> 이 값을 반환하기 원한다면 return 아무때나 실행
-> 메소드 호출은 여기서 끝남
*/
===========================
/* '값의 반환' : 메소드 내에서 메소드를 호출한 영역으로 값을 전달하는 것
* void : 값을 반환하지 않음을 의미
* 메소드의 이름 왼편에는 '메소드가 반화하는 값의 자료형 정보'를 삽입하게 되어 있음.
지금까지 정의한 모든 메소드들은 값을 반환하지 않았기 때문에 이곳에 항상 void가 위치했던 것 .
*/
public class MethodReturns {
public static void main(String[] args) {
int result;
// 메소드 호출문 -> adder라는 메소드 호출 결과로 9라는 값이 만들어져서 반환 -> result라는 변수에 9저장
result = adder(4, 5); // adder가 반환하는 값을 result에 저장
System.out.println("4 + 5 = " + result);
System.out.println("3.5 X 3.5 = " + square(3.5)); // 왼쪽에는 문장 & 오른쪽은 메소드 호출문 등장 (제곱)
}
// (void가 아닌 경우) int가 반환형, return이 값의 반환을 명령
public static int adder(int num1, int num2) { // int형 데이터를 내가 결과물로 만들어서 넘겨준다 & 반환해준다
int addResult = num1 + num2;
return addResult; // addResult의 값을 반환해라!
// return -> 값의 반환을 명령. return에 의해 실행이 되는 값의 반환 & 출력이라는 것은 그 메소드 호출문을 대체
}
// square 메소드를 호출(자바에게 힌트) : 결과물로 double형 실수가 반환이 되겠구나 ! 미리 메모리 공간 만들어놔야지! 이런 생각해두기.
public static double square(double num) {
return num * num; // num * num 의 결과를 반환 -> 메소드 호출 문장을 대신했다 !
}
}
/* adder / square 메소드의 의미
-> adder 메소드는 int형 값을 반환합니다.
-> square 메소드는 double형 값을 반환합니다. */
===========================
/* 메소드 : 기능 상자 - 정식 명칭 X, 느낌 살리는 정도만
code : 기능상자의 기능을 하게 하기 위함
* public, static 그리고 void가 왜 붙어있고 의미하는 바가 무엇인가?
-> 기능 상자의 특성을 선언해주는 main이라는 메소드의 특성을 설명해줌
당분간은 '그냥 붙여줘야 하는 키워드'로 기억
* 자바 프로그램은 main이라는 이름의 메소드에서부터 시작을 한다 ! -> '자바에서 정한 규칙'
* 출력은 있을 수도 있고 없을 수도 있음
* 메소드 hiEveryone의 실행을 명령하는 문장 -> '메소드 호출문'
* 메소드 호출 시 전달되는 값을 받기 위해 선언된 변수 -> '매개변수'
*/
public class MethodDef {
public static void main(String[] args) {
System.out.println("프로그램의 시작");
hiEveryone(12); // 12를 전달하며 hiEveryone 호출-> 3전달 ->
main메소드의 기능 잠시 멈춤. 문장 실행이 완료될 때까지!
hiEveryone(13); // 13을 전달하며 hiEveryone 호출
System.out.println("프로그램의 끝");
}
public static void hiEveryone(int age) { // 매개 변수가 하나인 메소드의 정의
System.out.println("좋은 아침입니다.");
System.out.println("제 나이는 " + age + "세 입니다");
}
}
========================
/*
* <매개변수> 1. 메소드 호출 시 선언되어, 전달되는 값을 저장한다.
2. 매개변수가 선언된 메소드 내에서만 유효한 변수이다.
* 정의된 메소드는 여러 번 호출 가능하며 메소드의 정의 위치는 프로그램에 영향을 미치지 않는다. main메소드가 언제 등장하건 아무런 차이가x
*/
public class Meethod2Param {
public static void main(String[] args) {
double myHeight = 175.9;
hiEveryone(12, 12.5); // 인자 12와 12.5의 전달 , 값과 값 사이 ,로 구별
hiEveryone(13, myHeight); // 인자 13과 변수 myHeight에 저장된 값 전달
byEveryone(); // 전달하는 인자 없음
}
// 매개변수가 둘인 메소드의 정의 ! 위에 있는 숫자와 아래 자료형의 '일치'
public static void hiEveryone(int age, double height) { // 매개변수가 있는 메소드의 정의
System.out.println("제 나이는 " + age + "세 입니다.");
System.out.println("저의 키는 " + height + "cm 입니다.");
}
/* 전달이 될 수는 있지만 내보내는게 x
전달을 받던 안받던 어떤 메소드를 호출을 하는 영역으로 뭔가를 만들어서 반환을 하는 것이 없다.
라는 의미로 void라는 선언이 존재 */
public static void byEveryone() { // 매개변수가 없는 메소드의 정의
System.out.println("다음에 뵙겠습니다.");
}
}
=====================
/* 변수의 스코프(Scope) : 임의의 변수에 대한 ' 변수의 접근 가능 영역 ' or 또는 ' 변수가 소멸되지 않고 존재 할 수 있는 영역'
-> 중괄호로 특정 영역을 감싸면, 해당 영역은 변수에 관한 별도의 스코프를 형성하게 된다 !
예를 들어서 다음과 같이 중괄호 내에 변수 num이 선언 되면
-> 진짜 위치상으로 지역변수의 성격을 가지면서 지역변수의 특성을 갖는 대표적 지역 변수
if(...) {
int num = 5; // 지금부터 닫는 중괄호 내에서만 변수 num 접근 가능
.... -> '지역변수 num' 어떤 중괄호든 상관 없이 중괄호 내에 선언이 되면 지역변수 : 지역 내에서만 유효한 변수
-> 중괄호를 벗어나는 순간 '소멸'되어 접근이 불가능
}
* 지역변수(Local Variacle) : 중괄호 내에 선언된 변수
*/
public class LocalVariable {
public static void main(String[] args) {
boolean ste = true; // (ste는 변수 1)
int num1 = 11; // (num1는 변수2)
/* num1은 이미 실행되었기 떄문에 또 선언을 할 수 x! 자바는 이를 허용하지 않는다 !
구분된 영역이라고 같은 변수를 또 선언하는 것은 안 좋은 코드 !
*/
if(ste) {
// int num1 = 22; // 주석 해제하면 컴파일 오류 발생
num1++;
System.out.println(num1);
} // (영역 1 -> 속한 지역을 벗어나면 지역변수 소멸)
{
int num2 = 33;
num2++;
System.out.println(num2);
} // (영역 2)
// System.out.println(num2); // 주석 해제하면 컴파일 오류 발생
/* 위 영역을 빠져나가면 소멸되기 때문에 저장한 num2 값을 참조해서 출력하겠다 하면 컴파일 오류!
(그 영역 내에서만 접근 이 가능하다)*/
}
}
/* EX) for문
-> 반복을 위한 변수 선언 등장 (지역변수의 성격을 가짐)
for(int num = 1; num < 5; num++) { -> 이 조건을 만족하지 못해 빠져나가는 순간 num이라는 변수도 '소멸'
// 변수 num의 접근 가능 영역, 추가로 변수 num 선언 불가 (for뭄ㄴ 내에서만 유효한 지역변수 num)
}
*/
/* -> 매개변수 NUM
public static void myFunc(int num) {
// 변수 num의 접근 가능 영역, 추가로 변수 num 선언 불가
-> 이 영역 내에서만 유효하다가 빠져나가는 순간 소멸 . 지역변수의 범주에 포함되는 매개변수(동일한 성격 가짐)
-> if) 총 10번 호출-> 순서대로 1~10까지 전달
-> 총 10개의 매개변수, 즉 지역 변수 선언 & 메모리 공간이 할당이 되었다가 소멸하는 과정을 거친다.
지역변수는 선언된 지역을 벗어나면 단순히 접근 불가만이 아니라 메모리상에서 삭제가 되는 것이다.
*/
=========================
public class 되나해본거 {
public static void main(String[] args) {
// 메소드 호출문 -> adder라는 메소드 호출 결과로 9라는 값이 만들어져서 반환 -> result라는 변수에 9저장
// adder가 반환하는 값을 result에 저장
System.out.println("4 + 5 = " + adder(4, 5));
System.out.println("3.5 X 3.5 = " + square(3.5)); // 왼쪽에는 문장 & 오른쪽은 메소드 호출문 등장 (제곱)
}
// (void가 아닌 경우) int가 반환형, return이 값의 반환을 명령
public static int adder(int num1, int num2) { // int형 데이터를 내가 결과물로 만들어서 넘겨준다 & 반환해준다
int addResult = num1 + num2;
return addResult; // addResult의 값을 반환해라!
// return -> 값의 반환을 명령. return에 의해 실행이 되는 값의 반환 & 출력이라는 것은 그 메소드 호출문을 대체
}
// square 메소드를 호출(자바에게 힌트) : 결과물로 double형 실수가 반환이 되겠구나 ! 미리 메모리 공간 만들어놔야지! 이런 생각해두기.
public static double square(double num) {
return num * num; // num * num 의 결과를 반환 -> 메소드 호출 문장을 대신했다 !
}
}
/* adder / square 메소드의 의미
-> adder 메소드는 int형 값을 반환합니다.
-> square 메소드는 double형 값을 반환합니다. */
'Java' 카테고리의 다른 글
| JAVA Programming(Ch 12.콘솔 출력) (0) | 2021.08.09 |
|---|---|
| JAVA Programming(Ch 11. 메소드 오버로딩) (0) | 2021.08.08 |
| JAVA Programming(Ch 10. 클래스 변수) (0) | 2021.08.08 |
| JAVA Programming(Ch 9.정보 은닉) (0) | 2021.08.08 |
| JAVA Programming(Ch 7) (0) | 2021.08.08 |