개발공부

JAVA쪼렙탈출기: 연산자

Yuniverse. 2023. 5. 13. 10:05
Python과 SQL만 써본 주니어 분석가. '개발공부를 해보고 싶다', '개발도 공부하긴 해야하는데...'는 말만 한지 어연 1년이 넘어가는 중, 이대로는 안되겠다 싶어 냅다 JAVA 수업 수강에 카드를 긁었다. 쪼렙 중의 쪼렙이 JAVA를 배워나가는 여정을 "JAVA 쪼렙 탈출기"라는 시리즈로 남길 예정이다.

 

산술 연산자

  • + : 덧셈
  • - : 뺄셈
  • * : 곱셈
  • / : 나눗셈
  • % : 나머지

위의 산술연산자는 파이썬을 쓸 때와 동일하다. (어느 언어에서나 사칙연산은 다 똑같이 적용하는 것 같다.) 하지만 파이썬에서는 / 를 쓰면 연산 결과가 float 로 나타나고, // 를 쓰면 연산 결과가 int 로 나타나서 / (나눗셈) , // (몫) 이런 식으로 생각했었는데 자바에서는 float 끼리 연산하면 결과도 float 로 나타나고, int 끼리 연산하면 결과도 int 로 나타나는 차이가 있었다. JAVA에서는 // 를 쓰면 에러가 발생하더라.

 

public class Ex01 {

	public static void main(String[] args) {
		
		int ia = 10, ib = 3;
        
		System.out.println(ia + " + " + ib + " = " + (ia+ib));
		System.out.println(ia + " - " + ib + " = " + (ia-ib));
		System.out.println(ia + " * " + ib + " = " + (ia*ib));
		System.out.println(ia + " / " + ib + " = " + (ia/ib));
		System.out.println(ia + " % " + ib + " = " + (ia%ib));
		
	}
	
}

[결과값]

10 + 3 = 13

10 - 3 = 7

10 * 3 = 30

10 / 3 = 3

10 % 3 = 1

 

만약에 위의 코드에서 ib를 float로 설정했다면, 결과값은 다음과 같이 바뀐다.

public class Ex01 {

	public static void main(String[] args) {
		
		int ia = 10;
		float ib = 3;
		
		System.out.println(ia + " + " + ib + " = " + (ia+ib));
		System.out.println(ia + " - " + ib + " = " + (ia-ib));
		System.out.println(ia + " * " + ib + " = " + (ia*ib));
		System.out.println(ia + " / " + ib + " = " + (ia/ib));
		System.out.println(ia + " % " + ib + " = " + (ia%ib));
		
	}
	
}

[결과값]

10 + 3.0 = 13.0

10 - 3.0 = 7.0

10 * 3.0 = 30.0

10 / 3.0 = 3.3333333

10 % 3.0 = 1.0

 

복합 대입 연산자

+=, -=, *= 등을 복합 대입 연산자라고 한다. 기호대로 연산한 후에 나온 결과를 왼쪽의 변수에 대입한다는 의미이다.

ex) a += b 는 a = a + b 와 같은 의미이다.

 

public class Ex02 {

	public static void main(String[] args) {
		
		int ic = 10;
		System.out.println("ic : " + ic);
		
		ic += 5;
		System.out.println("ic : " + ic);
		
		int id = 2;
		ic *= id;
		System.out.println("ic : " + ic);
		
	}
	
}

[결과값]

ic : 10

ic : 15

ic : 30

 

연산을 한 후 나온 결과를 왼쪽의 변수에 대입하는 것이기 때문에, 왼쪽에는 항상 변수가 있어야 한다.

5 += ic; 이런 식으로 쓰면 에러가 뜬다.

 

비교 연산자

부등호( >, <, >=, <= )가 비교 연산자이다. ==, != 는 각각 같다, 같지 않다 를 뜻하는 기호이다. 조건식에 따른 결과는 true 또는 false의 형태로 나오게 된다. 이상/이하의 부등호를 쓸 때는 =가 ><보다 오른쪽에 와야한다는 점만 주의하면 된다. => : 에러 발생

 

public class Ex03 {

	public static void main(String[] args) {
		
		int na = 10, nb = 7;
		
		System.out.println("na >= nb : " + (na >= nb));
		System.out.println("na == nb : " + (na == nb));
		System.out.println("na != nb : " + (na != nb));
		
	}
	
}

[결과값]

na >= nb : true

na == nb : false

na != nb : true

 

== 와 != 는 숫자형 데이터뿐만 아니라 문자형 데이터에서도 쓸 수 있다.

public class Ex03 {

	public static void main(String[] args) {
		
		String wordA = "abc";
		String wordB = "abc";
		String wordC = "abf";
		
		System.out.println(wordA == wordB);
		
	}
	
}

[결과값]

true

 

주의!

문자열 값이 같은지 확인할 때에는 == 연산자보다 equals() 메서드를 사용하는 것이 훨씬 좋다. 위의 코드 같은 경우는  System.out.println(wordA == wordB); 대신에 아래와 같이 쓰는 것이다.

System.out.println(wordA.equals(wordB));

[결과값]

true

 

== 연산자의 경우 참조 타입 변수들 간의 연산은 동일한 객체를 참조하는지, 다른 객체를 참조하는지 알아볼 때 사용되기 때문에, 우리가 생각하기엔 동일하다고 생각하는 결과도 다르다는 결과를 내는 경우가 있다. 예를 들면 아래의 코드는 == 연산자를 쓸 경우엔 false가 나온다. 하지만 equals() 메서드를 쓰면 true가 결과값으로 나온다.

public class Ex001 {
    public static void main(String[] args) {
        String s1 = "abcd";
        String s2 = new String("abcd");
		
        System.out.println(s1 == s2);
    }
}

 

논리 연산자

  • && : and 연산
    • 조건식_A && 조건식_B : A와 B 조건이 둘 다 참이어야 참
  • || : or 연산
    • 조건식_A || 조건식_B : A와 B 조건 둘 중 하나라도 참이면 참
  • ! : not 연산
    • !(조건식_C) : C의 결과가 참이면 거짓으로, 거짓이면 참으로 변경
public class Ex04 { 

	public static void main(String[] args) {
		
		int va = 10, vb = 7;
		boolean res;
		res = va > 9 && vb > 9;
		System.out.println("va > 9 && vb > 9 : " + res);
		
		res = va > 9 || vb > 9;
		System.out.println("va > 9 || vb > 9 : " + res);
		
		res = !(va > 9);
		System.out.println("!(va > 9) : " + res);
		
	}
	
}

[결과값]

va > 9 && vb > 9 : false

va > 9 || vb > 9 : true

!(va > 9) : false

 

증감 연산자

값을 1 증가시키거나, 1 감소 시킬 때 사용한다.

  • ++ : 1 증가
  • -- : 1 감소
  • ++n : 1 증가 후에 다른 연산
  • n++ : 다른 연산 후에 1 증가
  • --n : 1 감소 후에 다른 연산
  • n-- : 다른 연산 후에 1 감소

++n 과 n++ 가 헷갈릴 수도 있는데, 예를 들어보면 다음과 같다.

int a = 3;
int b;
b = ++a;

이 때 a = 4, b = 4 가 된다.

( a는 ++로 인해 3+1=4, b는 ++a의 값을 연산기호 = 로 받아서 4)

 

int a = 3;
int b;
b = a++;

이 때 a = 4, b = 3가 된다.

( b는 a의 값을 연산기호 = 로 받아서 3, a는 연산 이후 ++로 인해 3+1=4)

 

public class Ex05 {

	public static void main(String[] args) {
		
		int data = 5;
		int res = 0;
		res = ++data;
		System.out.println("data : " + data + " - res : " + res);
		
		res = data++;
		System.out.println("data : " + data + " - res : " + res);
		
		res = --data;
		System.out.println("data : " + data + " - res : " + res);
		
		res = data--;
		System.out.println("data : " + data + " - res : " + res);
		
		int a = 5;
		a++;
		System.out.println("a : " + a);
		
	}
	
}

[결과값]

data : 6 - res : 6

data : 7 - res : 6

data : 6 - res : 6

data : 5 - res :6

a : 6

 

증감연산자를 사용해서 복잡한 연산은 왠만하면 하지 않는다. 프로그래밍 언어마다 이 증감연산자에 대한 계산적인 차이가 존재하기 때문이다. 또, 증감연산자와 논리연산자를 동시에 사용할 때, 앞의 논리가 거짓이면 뒤의 논리는 작동하지 않는다.

예를 들면,

int n = 5;
boolean check = (++n > 6) && (++n > 6);
System.out.println("n : " + n + " - check : " + check);

이 코드에 대한 결과값은 n = 6, check = false 이다. ++n은 &&이라는 논리연산자를 두고 2번이 사용되었지만 n은 7이 되지 못한다. 앞의 논리가 거짓이었기 때문에 뒤의 ++n은 작동하지 않은채 코드가 끝났기 때문이다.

int m = 5;
boolean check2 = (++m > 6) || (++m > 6);
System.out.println("m : " + m + " - check2 : " + check2);

반면 이 코드에 대한 결과값은 m = 7, check = true 이다. 논리연산자 ||는 앞의 논리만 보고서는 참/거짓을 판단할 수 없기 때문에 뒤의 논리까지 작동하였고, 그 결과 ++m이 2번 모두 작동했기 때문에 m = 7이 된 것이다.

 

자동 형변환 & 강제 형변환

int ia = 5, ib = 2;
double div = 0;
div = ia / ib;

이 코드에서 div 값이 얼마가 나올 것 같은가? 정답은 2.0 이다. ia와 ib가 둘 다 int 이기 때문에 ia / ib 가 2 가 나오고, 이 2가 실수형인 div에 부여되었기 때문이다.

 

이 때 div 값이 2.5가 나오게 하려면 2가지 방법이 있다. 첫 번째는 실수형의 변수를 만들어서 연산에 해당 변수를 사용하는 것이다.

public class Ex06 {

	public static void main(String[] args) {
		
		int ia = 5, ib = 2;
		double div = 0;
		div = ia / ib;
		System.out.println("div : " + div);
		
		double da = 2;
		div = ia / da; 
		System.out.println("div : " + div);
	
	}
	
}

[결과값]

div : 2.0

div : 2.5

 

*9번째 줄에 double ib = 2;라고 기존에 있는 변수를 써버리면 에러가 발생한다.

이렇게 하는 것을 자동 형변환이라고 한다. 이런 방법 말고도 다음과 같이 코드를 작성해도 동일한 div 값 (2.5) 을 얻을 수 있다.

public class Ex06 {

	public static void main(String[] args) {
		
		int ia = 5, ib = 2;
		double div = 0;
		div = ia / ib;
		System.out.println("div : " + div);
	
		div = (double)ia / ib;
		System.out.println("div : " + div);
		
	}
	
}

[결과값]

div : 2.0

div : 2.5

 

사용하려는 데이터의 왼쪽에 '(변환자료형)'을 사용하면 실행시에 ( ) 안의 자료형으로 형변환되어 실행된다. 이는 ia 변수의 자료형 구조를 바꾸는 것이 아니라 = 연산이 일어나기 전에 ( ) 안의 자료형으로 변환하는 연산이 한 번 더 일어나는 것이기 때문에 에러가 발생하지 않는다. 이러한 방법을 강제 형변환이라고 한다. 

 

 

 

연산자는 아무래도 파이썬과 대다수가 동일하기 때문에 이해하기에 수월했다!