ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [ch3 자바 연산자] 연산자에 대한 모든 것
    프로그래밍 언어/JAVA 2022. 6. 7. 16:02
    연산자와 피연산자

     연산자는 '연산을 수행하는 기호'를 말한다. 예를 들어 '+' 기호는 덧셈 연산을 수행하며, '덧셈 연산자'라고 한다. 자바에서는 사칙연산(+, -, *, /)를 비롯해서 다양한 연산자를 제공한다. 연산자가 연산을 수행하려면 반드시 연산의 대상이 있어야하는데, 이것을 '피연산자(operand)'라고 한다. 

     

     'x+3'이라는 식이 있을 때, '+'는 두 피연산자를 더해서 그 결과를 반환하는 덧셈 연산자이고, 변수 x와 상수 3은 이 연산자의 피연산자이다. 이처럼 덧셈 연산자 '+'는 두 값을 더한 결과를 반환하므로, 두 개의 피연산자를 필요로한다. 연산자는 피연산자로 연산을 수행하고 나면 항상 결과값을 반환한다. 예를 들어 x의 값이 5일 때, 덧셈 연산 'x+3'의 결과값은 8이된다. 

     

    연산자와 피연산자를 조합하여 계산하고자 하는 바를 표현한 것을 '식(expression)'이라고 한다. 그리고 식을 계산하여 결과를 얻는 것을 '식을 평가(evaluation)한다'고 한다. 하나의 식을 평가하면, 단 하나의 결과를 얻는다. 

     

    식이 평가되어 하나의 결과값을 얻었고, 이 값을 쓰려면 대입 연산자 '='를 사용해서 변수와 같이 값을 저장할 수 있는 공간에 결과를 저장해야한다. 

     

    y = 4 * x + 3;
    System.out.println(y); 

     

    연산자의 종류

     

    피연산자의 개수로 연산자를 분류하기도 하는데, 피연산자의 개수가 하나면 '단항 연산자', 두개면 '이항 연산자', 세 개면 '삼항 연산자'라고 부른다. 대부분의 연산자는 '이항 연산자'이다.

     

     

    연산자의 우선순위

    식에서 사용된 연산자가 둘 이상인 경우, 연산자의 우선순위에 의해 연산순서가 결정된다.

    1. 산술 > 비교 > 논리 > 대입. 대입은 제일 마지막에 수행된다.
    2. 단항(1) > 이항(2) > 삼항(3). 단항 연산자의 우선순위가 이항 연산자보다 높다.
    3. 단항 연산자와 대입 연산자를 제외한 모든 연산의 진행방향은 왼쪽에서 오른쪽이다.

     

     

    증감 연산자 ++과 --

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

     

    증갑 연산자(++) : 피연산자의 값을 1 증가시킨다.
    감소 연산자(--) : 피연산자의 값을 1 감소시킨다.

    일반적으로 단항 연산자는 피연산자의 왼쪽에 위치하지만, 증감 연산자 '++'와 감소 연산자 '--'는 양쪽 모두 가능하다.

     

    타입 설명 사용예
    전위형 값이 참조되기 전에 증가시킨다. j = ++i;
    후위형 값이 참조된 후에 증가시킨다. j = i++;

     

     

    ※ 예제 1번 ※

    package ch3;
    
    public 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;
    		j=0; //결과 비교위해 i와 j 값을 다시 변경
    		
    		j=++i;
    		System.out.println("j=i++; 실행후, i=" + i +", j=" +j);
    	}
    }

    예제 1번 출력값

     

    위 예제 1번의 실행결과를 보면 i의 값은 두 경우 모두 1이 증가되어 6이 되지만, j의 값은 그렇지 않다.

    식을 계산하기 위해서는 식에 포함된 변수의 값을 읽어 와야 하는데, 전위형 변수(피연산자)의 값을 먼저 증가시킨 후에 변수의 값을 읽어오는 반면, 후위형은 변수의 값을 먼저 읽어온 후에 값을 증가시킨다.

     

     

     

    ※ 예제 2번 ※

     

    package ch3;
    
    public class Ex3_3 {
    
    	public static void main(String[] args) {
    		
    		int i=5, j=5;
    		System.out.println(i++);
    		System.out.println(++j);
    		System.out.println("i="+i+" j="+j);
    
    	}
    
    }

    예제 2번 출력값

     

    위의 결과를 살펴보면 i는 출력 후 i의 값을 증가시키는 후위연산자이기 때문에 값은 그대로 5가 출력되고,

    j는 전위연산자로 i의 값을 증가시킨 후 그 값을 참조하여 출력하기 때문에 값은 6이 출력된다,

    3번째 줄에서 i와 j의 값을 참조할때는 모두 증가된 값인 6이 출력된다. (여기서 헷갈리지 말자!)

     

     

    형변환 연산자

    같은 타입뿐만 아니라 서로 다른 타입 간의 연산을 수행하는 경우도 있다. 이럴 때는 연산을 수행하기 전에 타입을 일치시켜야 하는데, 변수나 리터럴의 타입을 다른 타입으로 변환하는 것을 '형변환(casting)'이라고 한다.  형변환하고자 하는 변수나 리터럴 앞에 변환하고자 하는 타입을 괄호와 함께 붙여주기만 하면 된다. (타입) 피연산자

     

    double d = 85.4;
    int score = (int)d;

    위와 같은 코드가 있을 때 double 형의 85.4를 int형으로 형변환하여 85라는 값을 score에 저장한다. 

    이렇게 형변환을 했다고 하더라도 d의 값을 출력해보면 그대로 85.4가 출력된다. 따라서 피연사지인 변수 d의 값은 형변환 후에도 아무런 변화가 없다는 걸 알 수 있다.

     

     

     

    자동 형변환

    형변환을 하는 이유는 주로 서로 다른 두 타입을 일치시키기 위해서인데, 형변환을 생략하면 컴파일러가 알아서 자동적으로 형변환을 한다. 그래서 표현범위가 좁은 타입에서 넓은 타입으로 형변한하는 경우에는 값 손실이 없으므로 두 타입 중에서 표현범위가 더 넓은 쪽으로 형변화된다. 만약 int 형과 double형을 더한다면 double형의 결과값이 나온다.!

     

     

    산술 변환

    이항 연산자는 두 피연산자의 타입이 일치ㅐ야 연산이 가능하므로, 피연산자의 타입이 서로 다르다면 연산 전에 형변환 연산자로 타입을 일치시켜야한다. 이처럼 연산 전에 연산자 타입의 일치를 위해 자동으로 형변환되는 것을 '산술 변환' 또는 '일반 산술 변환'이라 하며, 이 변환은 이항 연산에서만 아니라 단항연산에서도 일어난다. '산술 변환'의 규칙은 다음과 같다

     

    1. 두 피연산자의 타입을 같게 일치시킨다. (보다 큰 타입으로 일치)
    long + int -> long + long -> long
    2. 피연산자의 타입이 int보다 작은 타입이면 int로 변환된다.
    byte + short -> int + int -> int 

     

    두 번째 규칙은 int보다 작은 타입으로 변환되는데, 이는 char이나 short의 표현범위가 좁아서 연산중에 오버플로우(overflow)가 발생할 가능성이 높기 때문에 있는 것이다. 여기서 한 가지 주목해야할 점은 연산결과의 타입인데, 연산결과의 타입은 피연산자의 타입과 일치한다. 따라서 5/2의 값이 2.5가 아닌 2인 것이다. 만약 2.5라는 실수의 값을 얻으려면 int형보다 큰 타입인 float와 같은 실수형으로 형변환해야한다. 

     

     

    Math.round()로 반올림하기

    반올림을 하려면 Math.round()를 사용하면 된다. 이 메서드는 소수점 첫째 자리에서 반올림한 결과를 정수로 반환한다.

    long result = Math.round(4.52); // result에 5가 저장된다.

     

    만약 소수점 첫째 자리가 아닌 다른 자리에서 반올림 하려면 10의 n제곱으로 적절히 곱하고 나눠야한다. 

    double pi = 3.141592;
    double shortPi = Math.round(pi*1000)/ 1000.0; //결과는 3.142

    이 말이 뭐냐하면 pi의 값을 소수점 넷째 자리인 5에서 반올림해서 3.142가 출력된 것이다. 즉) Math.round로 pi*1000인 3142의 값을 만들어내고 이를 다시 1000.0으로 나누면 3.142가 되는 것! 만약) 1000.0이 아닌 1000으로 나눴다면  int 나누기 int이기 때문에 3이라는 값이 나온다. 따라서 실수형인 1000.0으로 나눠준 것이다. 

     

     

    비교 연산자

    비교 연산자는 두 피연산자를 비교하는 데 사용되는 연산자다. 주로 조건문과 반복문의 조건식에 사용되며, 연산결과는 오직 true와 false 둘 중의 하나이다. 

     

    • 대소비교 연산자 < > <= >=

    두 피연산자의 값의 크기를 비교하는 연산자로 참이면 true, 거짓이면 false를 결과로 반환한다. 기본형 중에서는 boolean을 제외한 나머지 자료형에 다 사용할 수 있지만 참조형에는 사용할 수 없다.

     

    • 등가비교 연산자 == !=

    두 피연산자의 값이 같은지 또는 다른지를 비교하는 연산자이다. 대소비교 연산자와 달리 모든 자료형(기본형, 참조형)에 사용할 수 있다. 기본형의 경우 변수에 저장되어 있는 값이 같은지를 알 수 있고, 참조형의 경우 객체의 주소값을 저장하기 때문에 두 개의 피연산자(참조변수)가 같은 객체를 가리키고 있는지 주소값이 같은지를 알 수 있다. 기본형과 참조형은 서로 형변환이 가능하지 않기 때문에 등가비교 연산자로 기본형과 참조형을 비교할 순 없다. 

     

    문자열의 비교

    문자열을 비교할 때는, 비교 연산자 '==' 대신 equals()라는 메서드를 사용해야한다. 비교 연산자는 두 문자열이 완전히 같은 것인지 비교할 뿐이므로, 문자열의 내용이 같은지 비교하기 위해서는 equals()를 사용하는 것이다. equlas()는 비교하는 두 문자열이 같으면 true, 다르면 false를 반환한다.

    String str = new String("abc");
    boolean result = str.equlas("abc"); // 내용이 같으므로 result에 true가 저장된다. 

    원래 String은 클래스 이므로 new String("abc"); 이런식으로 객체를 생성해야하는데, 생략이 가능해서 간편하게 보통

    String str = "abc";이렇게 사용한다. 

     

    String str1 = "abc";
    String str2 = new String("abc");

    str1 == "abc" ; //true
    str2 =="abc"; //false 
    str1.equlas("abc"); //true
    str2.equlas("abc"); //true

    str2와 "abc"의 내용이 같은데도 비교연산자인 '=='로 비교하면, flase라는 결과를 얻는다. 내용은 같지만 서로 다른 객체라서 그렇다. 그러나 equlas()는 객체가 달라도 내용이 같으면 true를 반환한다. 그래서 문자열을 비교할 때는 항상 equals()를 사용해야 한다는 것을 기억하자. 만일 대소문자를 구별하지 않고 비교하고 싶으면 equlas()대신 equlasIgnoreCase()를 사용하면 된다. 

     

     

    논리연산자 && ||

    논리연산자는 둘 이상의 조건을 '그리고(AND)'나 '또는(OR)'으로 연결하여 하나의 식을 표현할 수 있게 해준다. 

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

    그럼 자주 사용될만한 몇 가지 예를 통해 어떻게 실제로 사용되는지 알아보자.

    1.  x는 10보다 크고, 20보다 작다
      x > 10 && x < 20
    2. i는 2의배수 또는 3의 배수이다.
      i%2==0 || i%3==0
    3. i는 2의 배수 또는 3의 배수이지만 6의 배수는 아니다.
      (i%2==0 || i%3==0) && i%6!=0
      여기서 괄호를 사용하는 이유는 '&&'가 '||'보다 우선순위가 높기 때문이다. 
    4. 문자 ch는 숫자('0'~'9')이다.
      '0' <= ch &&  ch <='9'
    5. 문자 ch는  대문자 또는 소문자이다.
      ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z')

     

    ※ 예제 3번 ※

    package ch3;
    
    import java.util.Scanner;
    
    public class Ex3_15 {
    
    	public static void main(String[] args) {
    		
    		Scanner sc = new Scanner(System.in);
    		char ch = ' ';
    
    		while(true) {
    		System.out.println("문자를 하나 입력하세요 : ");
    		String input = sc.nextLine();
    		ch = input.charAt(0);
    
    		if(('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z')) {
    			System.out.println("입력하신 문자는 영문자 입니다.");
    		}
    		if(('0'<=ch && ch<='9')) {
    			System.out.println("입력한 문자는 숫자입니다.");
    		}
    		
    	}
    		
    	}
    
    }

    예제 3번 출력값

     

    조건 연산자

    조건 연산자는 조건식, 식1, 식2 모두 세 개의 피연산자를 필요로 하는 삼항 연산자이며, 삼항 연산자는 조건 연산자 하나뿐이다. 

    조건 연산자는 첫 번째 피연사자인 조건식의 평가결과에 따라 다른 결과를 반환한다. 조건식의 평가결과가 true이면 식1이, flase이면 식2가 연산결과가 된다. 가독성을 높이기 위해 조건식을 괄호()로 둘러싸는 경우가 많지만 필수는 아니다.

    result = ( x > y) ? x : y; 

     

     만약 x의 값이 5, 의 값이 3 이라면 (5 >3 )? 5:3; 조건식의 결과는 참이므로 5를 결과값으로 가진다. 

     

     

    대입 연산자

    대입 연산자는 변수와 같은 저장공간에 값 또는 수식의 연산결과를 저장하는데 사용된다. 이 연산자는 오른쪽 피연산자의 값을 왼쪽 피연산자에 저장한다. 그리고 저장된 값을 연산결과로 반환한다.

    대입 연산자는 연산자들 중에서 가장 낮은 우선순위를 가지고 있기 때문에 식에서 제일 나중에 수행된다. 그리고 앞서 배운 것처럼 연산 진행 방향이 오른쪽에서 왼쪽이기 때문에 'x=y=3;' 에서 'y=3'이 먼저 수행되고 그다음에 'x=y'가 수행된다.

     

    복합 대입 연산자

    반응형

    댓글

Designed by Tistory.