자바의 정석 <기초편> 📌chapter3. 연산자

모깅·2023년 1월 29일
0

📖 01. 연산자와 피연산자

연산자 : 연산을 수행하는 기호
피연산자 : 연산의 대상

  • x + 3
    x , 3 -> 피연산자
    + -> 연산자

📖 02. 연산자의 종류

  • 피연산자
    -> 1개 : 단항 연산자
    -> 2개 : 이항 연산자
    -> 3개 : 삼항 연산자

📖 03. 연산자의 우선순위

상식선에서 해결 할 것!


📖 04. 연산자의 결합법칙

  1. 산술 > 비교 > 논리 > 대입. 대입은 제일 마지막에 수행된다.
  2. 단항(1) > 이항(2) > 삼항 (3).
  3. 단항, 대입을 제외한 모든 연산의 진행방향은 오른쪽이다.

<예제 3-1 >

✍️ 입력

class Ex3_1 {
	public static void main(String[] args) {
		int x, y;

		x = y = 3; // y에 3이 저장된 후에, x에 3이 저장된다.
		System.out.println("x=" + x);
		System.out.println("y=" + y);
	}
}

💻 출력
x=3
y=3


📖 05. 증감 연산자 ++과--

  • 증감 연산자는 피연산자에 저장된 값을 1증가 또는 감소시킨다. 증감 연산자의 피연산자로 정수와 실수가 모두 가능하지만, 상수는 값을 변경할 수 없으므로 가능하지 않다.

  • 증감 연산자가 독립적으로 쓰이면 전위형과 후위형의 차이는 없다
    ++i // 전위형. i의 값을 1 증가시킨다.
    i++ // 후위형. 위문장과 같다.

<예제 3-2 >

✍️ 입력

class Ex3_2 {
	public static void main(String args[]) {
		int i=5, j=0;

		j = i++;
		System.out.println("j=i++; 실행 후, i=" + i +", j="+ j);

		i=5;        // 결과를 비교하기 위해, i와 j의 값을 다시 5와 0으로 변경
		j=0;

		j = ++i;
		System.out.println("j=++i; 실행 후, i=" + i +", j="+ j);
	}
}

💻 출력
j=i++; 실행 후, i=6, j=5
j=++i; 실행 후, i=6, j=6

<예제 3-3 >

✍️ 입력

class Ex3_3 {
	public static void main(String args[]) {
		int i=5, j=5;
		System.out.println(i++);  // i의 값을 출력 후, 1 증가
		System.out.println(++j);  // j의 값을 1 증가 후, 출력
		System.out.println("i = " + i + ", j = " +j);
	}
}

💻 출력
5
6
i = 6, j = 6


📖 06. 부호 연산자

<예제 3-4 >

✍️ 입력

class Ex3_4 {
	public static void main(String[] args) {
		int i = -10;
		i = +i;
		System.out.println(i);

		i = -10;
		i = -i;
		System.out.println(i);
	}
}
}

💻 출력
-10
10


📖 07. 형변환 연산자

  • 형변환이란, 변수 또는 상수의 타입을 다른 타입으로 변환하는 것
    -> '(타입)피연산자' 형태
    -> 괄호()는 '캐스트 연산자' 또는 '형변환 연산자' 라고 한다.
    -> 형변환을 '캐스팅(casting)'이라고도 한다.

  • double d = 85.4;
    int score = (int)d;
    => int score = (int)d; -> int score = (int)85.4; -> int score = 85;
    - 형변환은 지정된 타입으로 형변환하고 그 결과를 반환할 뿐
    d에는 아무런 변화가 없다.

<예제 3-5 >

✍️ 입력

class Ex3_5 {
	public static void main(String[] args) {
		double d = 85.4;
		int score = (int) d;
		System.out.println("score=" + score);
		System.out.println("d=" + d);
	}
}

💻 출력
score=85
d=85.4


📖 08. 자동 형변환


큰 변수에 작은 것을 담는 것은 형변환이 알아서 된다.
하지만 반대의 경우 ()로 강제 형변환을 해줘야 한다.


📖 09. 사칙 연산자

<예제 3-6 >

✍️ 입력

class Ex3_6 {
	public static void main(String args[]) { 
		int a = 10;
		int b = 4;

		System.out.printf("%d + %d = %d%n",  a, b, a + b);
		System.out.printf("%d - %d = %d%n",  a, b, a - b);
		System.out.printf("%d * %d = %d%n",  a, b, a * b);
		System.out.printf("%d / %d = %d%n",  a, b, a / b);
		System.out.printf("%d / %f = %f%n",  a, (float)b, a / (float)b);
	}
}

💻 출력
10 + 4 = 14
10 - 4 = 6
10 * 4 = 40
10 / 4 = 2
10 / 4.000000 = 2.500000

  • int / int 는 결과도 int
    -> 실수의 결과를 얻고 싶다면 피연산중 하나를 실수형(double, float)으로 바꾸자.

📖 10. 산술 변환

  • 이항 연산자는 피연산자의 타입을 맞춰줘야 한다.
  • 연산 결과의 타입은 피연산자의 타입과 일치한다.

<예제 3-7 >

✍️ 입력

class Ex3_7 {
	public static void main(String[] args) {
		System.out.println(5/2);
		System.out.println(5/(float)2);  //  (float)5/2의 결과도 동일
	}
}

💻 출력
2
2.5

<예제 3-8 >

✍️ 입력

class Ex3_8 {
	public static void main(String[] args) {
		byte a = 10;
		byte b = 30;
		byte c = (byte)(a * b);
		System.out.println(c);
	}
}

💻 출력
44

  1. a, b가 연산할 땐 int형으로 바뀌기 때문에 byte 변수 c에 넣을 수 없다.
    -> (byte)로 형변환 하자.
  2. 출력값이 byte(~127) 단위를 넘는다. 오버플로우 발생해서 44 출력.

<예제 3-9 >

✍️ 입력

class Ex3_9 {
	public static void main(String args[]) { 
		int a = 1_000_000;    // 1,000,000   1백만 
		int b = 2_000_000;    // 2,000,000   2백만 

		long c = a * b;       // a * b = 2,000,000,000,000 ?

		System.out.println(c);
	}
}

💻 출력
-1454759936

  • a * b 의 결과값은 int 형이다. 그러나 결과값이 int범위를 넘어가기 때문에 자동 형변환 되더라도 원하는 답이 나오지 않는다.
    -> 올바른 결과를 얻기 위해선 a 또는 b를 'long'으로 형변환 해야한다.

<예제 3-10 >

✍️ 입력

class Ex3_10 {
	public static void main(String args[]) { 
		long a = 1_000_000 * 1_000_000;
		long b = 1_000_000 * 1_000_000L;

		System.out.println("a="+a);
		System.out.println("b="+b);
	}
}

💻 출력
a=-727379968
b=1000000000000


📖 11. Math.round()로 반올림하기

이 메소드는 소수점 첫째 자리에서 반올림 한 결과를 정수로 반환한다.
-> 만일 소수점 첫째 자리가 아닌 다른 자리에서 반올림을 하려면 10의 n제곱으로 적절히 곱하고 나누어야 한다.

<예제 3-11 >

✍️ 입력

class Ex3_11 {
	public static void main(String args[]) { 
		double pi = 3.141592; 
		double shortPi = Math.round(pi * 1000) / 1000.0;
		System.out.println(shortPi);
	}
}

💻 출력
3.142


📖 12. 나머지 연산자

<예제 3-12 >

✍️ 입력

class Ex3_12 {
	public static void main(String args[]) { 
		int x = 10;
		int y = 8;

		System.out.printf("%d을 %d로 나누면, %n", x, y); 
		System.out.printf("몫은 %d이고, 나머지는 %d입니다.%n", x / y, x % y); 
	}
}

💻 출력
10을 8로 나누면,
몫은 1이고, 나머지는 2입니다.

<예제 3-13 >

✍️ 입력

class Ex3_13 { 
	public static void main(String[] args) { 
		System.out.println(-10%8); 
		System.out.println(10%-8); 
		System.out.println(-10%-8); 
	} 
}

💻 출력
-2
2
-2

  • 나머지 연산자(%)는 나누는 수로 음수도 허용한다. 그러나 부호는 무시되므로 결과는 음수의 절대값으로 나눈 나머지와 결과가 같다.
    -> 피연산자의 부호를 모두 무시하고, 나머지 연산을 한 결과에 왼쪽 피연산자의 부호를 붙이자.

📖 13. 비교 연산자

  1. 연산결과 true or false
  2. 비교연산자 연시 이항 연산자이므로 피연산자의 타입이 다를 경우 자료형의 범위가 큰 쪽으로 자동 형변환 후 비교하니 주의하자.
  • 대소비교 연산자 < > <= >=
  • 등가비교 연산자 == !=

📖 14. 문자열의 비교

  • 문자열 비교할ㄹ 때 '==' 대신 equals() 메소드 사용
    -> '=='는 완전히 같은 것인지만 확인.
    -> equals()는 내용까지 같은지 확인.

<예제 3-14 >

✍️ 입력

class Ex3_14 {
	public static void main(String[] args) {
		String str1 = "abc";
		String str2 = new String("abc");

		System.out.printf("\"abc\"==\"abc\" ? %b%n", "abc"=="abc");
		System.out.printf(" str1==\"abc\" ? %b%n",    str1=="abc");
		System.out.printf(" str2==\"abc\" ? %b%n",    str2=="abc");
		System.out.printf("str1.equals(\"abc\") ? %b%n", str1.equals("abc"));
		System.out.printf("str2.equals(\"abc\") ? %b%n", str2.equals("abc")); 
		System.out.printf("str2.equals(\"ABC\") ? %b%n", str2.equals("ABC"));
		System.out.printf("str2.equalsIgnoreCase(\"ABC\") ? %b%n", str2.equalsIgnoreCase("ABC"));
	}
}

💻 출력
"abc"=="abc" ? true
str1=="abc" ? true
str2=="abc" ? false
str1.equals("abc") ? true
str2.equals("abc") ? true
str2.equals("ABC") ? false
str2.equalsIgnoreCase("ABC") ? true

str2와 "abc"의 내용이 같은데도 '=='로 비교하면 false의 결과를 얻는다.
-> 내용은 같지만 서로 다른 객체기 때문이다.
그러나 equals()는 객체가 달라도 내용이 같으면 true를 반환한다.
-> 대소문자도 구별하지 않고 비교하고 싶다면? equalsIgnoreCase()
를 사용하자.


📖 15. 논리 연산자 && ||

|| (OR결합) : 피연산자 중 어느 한 쪽이 true이면 true를 결과를 얻는다.
&& (AND결합) : 피연사자 양쪽 모두 true이어야 true를 결과로 얻는다.

<예제 3-15 >

✍️ 입력

import java.util.*;  // Scanner클래스를 사용하기 위해 추가

class Ex3_15 {
	public static void main(String args[]) { 
		Scanner scanner = new Scanner(System.in);
		char ch = ' ';

		System.out.printf("문자를 하나 입력하세요.>");

		String input = scanner.nextLine();
		ch = input.charAt(0);

		if('0' <= ch && ch <= '9') {
			System.out.printf("입력하신 문자는 숫자입니다.%n");
		}

		if(('a' <= ch && ch <= 'z') || ('A'<= ch && ch <= 'Z')) {
			System.out.printf("입력하신 문자는 영문자입니다.%n");
		}
	} // main
}

💻 출력
결과 1)
문자를 하나 입력하세요.>7
입력하신 문자는 숫자입니다.

결과 2)
문자를 하나 입력하세요.>a
입력하신 문자는 영문자입니다.


📖 16. 논리 부정 연산자 !

  • 피연사자가 true이면 false로 false였다면 true로 변환한다.

<예제 3-16 >

✍️ 입력

class Ex3_16 {
	public static void main(String[] args) { 
		boolean b = true; 
		char ch = 'C';
		
		System.out.printf("b=%b%n", b);
		System.out.printf("!b=%b%n", !b);
		System.out.printf("!!b=%b%n", !!b);
		System.out.printf("!!!b=%b%n", !!!b);
		System.out.println();

		System.out.printf("ch=%c%n", ch);
		System.out.printf("ch < 'a' || ch > 'z'=%b%n", ch < 'a' || ch > 'z');
	  	System.out.printf("!('a'<=ch && ch<='z')=%b%n", !('a'<= ch && ch<='z'));
	   System.out.printf("  'a'<=ch && ch<='z' =%b%n", 'a'<=ch && ch<='z');
	} // main의 끝
}

💻 출력
b=true
!b=false
!!b=true
!!!b=false

ch=C
ch < 'a' || ch > 'z'=true
!('a'<=ch && ch<='z')=true
'a'<=ch && ch<='z' =false


📖 17. 조건 연산자

  • 조건식 ? 식1 : 식2
    -> 조건식이 참 : 식1, 거짓 : 식2

<예제 3-17 >

✍️ 입력

class Ex3_17 {
	public static void main(String args[]) { 
		int  x, y, z;
		int  absX, absY, absZ;
		char signX, signY, signZ;

		x = 10;
		y = -5;
		z = 0;

		absX = x >= 0 ? x : -x;  // x의 값이 음수이면, 양수로 만든다.
		absY = y >= 0 ? y : -y;
		absZ = z >= 0 ? z : -z;
		signX = x > 0 ? '+' : ( x==0 ? ' ' : '-');  // 조건 연산자를 중첩
		signY = y > 0 ? '+' : ( y==0 ? ' ' : '-'); 
		signZ = z > 0 ? '+' : ( z==0 ? ' ' : '-'); 

		System.out.printf("x=%c%d%n", signX, absX);
		System.out.printf("y=%c%d%n", signY, absY);
		System.out.printf("z=%c%d%n", signZ, absZ);
	}
}

💻 출력
x=+10
y=-5
z= 0


📖 18. 대입 연산자

  • = : 오른쪽 피연산자의 값(식이라면 평가값)을 왼쪽 피연산자에 저장한다.
  • lvalue와 rvalue
    -> 대입 연산자의 왼쪽 피연사자를 'lvalue'라고 하고 오른쪽을 'rvalue'라고 한다.
    -> rvalue는 아무거나 사용해도 된다. but lvalue는 변수처럼 값을 변경 할 수 있는 것이어야 한다.

📖 19. 복합 대입 연산자

  • 마지막만 조심하자.





[출처] 자바의 정석 <기초편> (남궁 성 지음)

profile
멈추지 않기

0개의 댓글