변수와 자료형, 연산자
자료형의 종류와 크기

정수 자료형
1. byte
- 1byte = 8bit
- 바이트 단위의 정보를 저장하거나 통신할 때 주로 사용
- 표현할 수 있는 수의 범위 : -27 ~ 27-1 <= ( -128 ~ 127 )
2. short
- 2byte
- 표현할 수 있는 수의 범위 : -215 ~ 215-1 <= ( -32768 ~ 32767 )
3. int
- 4byte
- 표현할 수 있는 수의 범위 : -231 ~ 231-1 <= ( -2147483648 ~ 2147483647 )
- 가장 많이 사용하는 자료형
- 컴퓨터에서 정수로 연산을 할 때 4바이트 단위로 처리하는 것이 가장 효율적임.
4. long
- 8byte
- 표현할 수 있는 수의 범위 : -263 ~ 263-1 <= ( -18,446,744,073,709,551,616 ~ 18,446,744,073,709,551,615 )
- 주의할 점
- 자바는 모든 정수값을 int형으로 처리함.
- 만약 long을 써도 int의 크기에서 벗어날 경우 에러가 남.
- 컴파일러에게 long으로 처리하라고 알려주어야 하기 때문에 long으로 선언하여도 숫자 뒤에 식별자인 L이나 l을 사용
- 대부분 가독성을 위해 대문자를 사용
- ex) long num = 123456789000l <-- 구분 안감. / long num = 123456789000L <-- 바로 구분이 됨.
다른 타입끼리 연산 시 자동으로 높은 쪽 캐스팅이 됨.
실수 자료형
1. float
- 4byte
- 자바에서 실수는 double형을 기본으로 사용
- long의 식별자와 같이 오류방지를 위해 F 또는 f를 붙여야 함.
- 똑같이 대부분 대문자 사용 ex) float num = 3.14F
2. double
- 8byte
- 자바에서 실수는 double형을 기본으로 사용
- float에 비해 더 정밀하게 실수를 표현할 수 있음.
부동 소수점 방식
- 실수 값 0.1은 1.0 X 10-1로 표현할 수 있음.
- 가수 부분(1.0)과 지수 부분(-1)을 나누어서 실수를 나타내는 방식
문자 자료형
char
- 2Byte
- 문자는 아스키 코드 값으로 '인코딩' 된 후 컴퓨터에 저장됨.
- 숫자도 저장 가능하지만 음수를 넣으면 오류가 생김.
논리 자료형
boolean
상수와 리터럴, 형 변환
상수 : 항상 변하지 않는 값
상수를 사용하기 위해선 final 예약어를 사용해야 함.
ex) final double PI = 3.14;
상수 이름은 대문자를 주로 사용.
리터럴 : 프로그램에서 사용하는 모든 숫자, 문자, 논리값을 일컫는 말
형 변환 : 다른 자료형을 하나의 자료형으로 통일한 후 연산을 하는 과정
컴퓨터는 정수와 실수의 표현되는 방식이 전혀 다르기 때문에 하나로 통일 후 연산을 함.
크게 묵시적 형 변환(자동 형 변환)과 명시적 형 변환(강제 형 변환)으로 구별됨.
묵시적 형 변환의 관계
Byte -> short, char -> int -> long -> float -> double
화살표 방향으로 자동 형 변환이 됨.
- 바이트 크기가 작은 자료형에서 큰 자료형으로 대입하는 경우
- 덜 정밀한 자료형에서 더 정밀한 자료형으로 대입하는 경우
- 연산 중에 자동으로 변환되는 경우
명시적 형 변환
묵시적 형 변환과 반대의 경우로 생각할 수 있음.
- 바이트 크기가 큰 자료형에서 작은 자료형으로 대입하는 경우
- 더 정밀한 자료형에서 덜 정밀한 자료형으로 대입하는 경우
- 연산 중 형 변환
연산자
기본 연산자
연산자는 항의 개수에 따라 단항 연산자, 이항 연산자, 삼항 연산자로 나눌 수 있다.
- 대입 연산자
- 부호 연산자
- 산술 연산자
- 증,감 연산자
- 관계 연산자
- 논리 연산자
- 복합 대입 연산자
- 조건 연산자
1. 대입 연산자
- 우선순위가 가장 낮은 연산자
- 오른쪽 변수 값이나 식의 연산 결과 값을 왼쪽 변수에 대입
- ex) int a = 1;
2. 부호 연산자
- +, -
- 더하기, 빼기에 스는 이항 연산자면서 부호를 나타내는 단항 연산자로도 사용 가능
- ex) int num = -3
3. 산술 연산자
- 사칙연산
- +, -, *, /, %
- + : 덧셈
- - : 뺄셈
- * : 곱
- / : 나누어 몫
- % : 나누어 나머지
4. 증,감 연산자
- 연산자 앞이나 뒤에 사용하여 값을 1 증가, 1 감소
- ++, --
- ++ : 1 증가
- -- : 1 감소
- 위치에 따라 연산 결과 차이가 있음.
5. 관계 연산자
- 두 개의 항의 관계 여부 검사
- 오른쪽이 큰 기준으로
- > : 왼쪽 항이 크면 참, 아니면 거짓
- < : 오른쪽 항이 크면 참, 아니면 거짓
- >= : 왼쪽 항이 오른쪽 항보다 크거나 같으면 참, 아니면 거짓
- <= : 오른쪽 항이 왼쪽 항보다 크거나 같으면 참, 아니면 거짓
- == : 두 개의 항이 같으면 참, 아니면 거짓
- != : 두 개의 항이 다르면 참, 아니면 거짓
6. 논리 연산자
- 명제
- &&(논리 곱) : 모두 참인 경우에만 참
- ||(논리 합) : 둘 중 하나가 참인 경우 참
- !(부정) : 참은 거짓으로, 거짓은 참으로
7. 복합 대입 연산자
- 대입 연산자와 다른 연산자를 조합해 하나의 연산자처럼 사용하는 연산자
- 우선순위가 가장 낮음.
- += : 두 항의 값을 더해서 왼쪽 항에 대입
- -= : 왼쪽 항에서 오른쪽 항을 빼고 값을 왼쪽 항에 대입
- *= : 두 항의 값을 곱해서 왼쪽 항에 대입
- /= : 왼쪽 항을 오른쪽 항으로 나누어 몫을 왼쪽 항에 대입
- %= : 왼쪽 항을 오른쪽 항으로 나누어 나머지를 왼쪽 항에 대입
- <<= : 비트를 왼쪽으로 이동 후 값을 왼쪽항에 대입
- >>= : 비트를 오른쪽으로 이동하고 값을 왼쪽 항에 대입
- >>>= : 비트를 오른쪽으로 이동하고 값을 왼쪽 항에 대입
- &= : 두 항의 & 비트 연산 후 값을 왼쪽 항에 대입
- |= : 두 항의 | 비트 연산 후 값을 왼쪽 항에 대입
- ^= : 두 항의 ^ 비트 연산 후 값을 왼쪽 항에 대입
8. 조건 연산자
- 삼항 연산자
- 조건 ? 결과1 : 결과2;
- ex) int num = (10 > 7) ? '참' : '거짓' <-- 결과 '참'
비트 연산자
- 비트 단위로 연산이 이루어지는 연산자
- 프로그램에서 특정 값을 만들거나 연산할 때 사용
- 비트 논리 연산자
- &, |, ^, ~
- & 연산자
- 두 개의 비트 값이 모두 1인 경우에만 연산의 결과 값이 1이 됨.
- ex)
- int num1 = 5; <- 2진수로 00000101
- int num2 = 10; <- 2진수로 00001010
- int result = num1 & num2;
- num1 : 00000101, num2 : 00001010 이기 때문에 결과 값은 0이 된다.
- | 연산자
- 비트 값이 하나라도 1이면 연산 결과 값이 1이 됨.
- ex)
- int num1 = 5; <- 2진수로 00000101
- int num2 = 10; <- 2진수로 00001010
- int result = num1 | num2;
- 연산 결과 00001111 <- 10진수 변환 시 15기 때문에 결과값이 15가 됨.
- ^ 연산자
- 같은 값이면 0, 다른 값이면 1
- ex)
- int num1 = 5; <- 2진수로 00000101
- int num2 = 7; <- 2진수로 00000111
- int result = num1 ^ num2;
- num1 : 0101, num2 : 0111 이기 때문에 0010이 된다. 결과값 : 2
- ~ 연산자
- 0은 1로, 1은 0으로 바꿈.
- ex)
- int num1 = 5; <- 2진수로 00000101
- int result = ~num1;
- ~num1 : 11111010으로 -6이 됨.
- 11111010 : 반전시긴 후 + 1 <- 00000101 + 1 = 00000110 <= 6이므로 -6
보수
주어진 수를 다른 수로 바꾸는 연산을 의미함.
이진수에서 주로 사용된다.
- 2의 보수
- 음수를 표현하기 위한 방법
-
양수의 이진수 표현 : 절대값이 양수인 이진수를 구함.
-
비트 반전 : 모든 비트를 반전시킴. 0은 1로 1은 0으로
-
1 더하기 : 반전된 이진수에 1을 더함.
-
ex) -6을 2의 보수로 표현하기
-
양수 6을 8비트 이진수로 표현하면 00000110
-
비트를 반전시키면 11111001
-
1을 더하면 11111010이 됨.
- 비트 이동 연산자
- <<, >>, >>>
- 시프트 연산자라고도 부름.
-
<< 연산자
-
왼쪽으로 비트를 이동하는 연산자
-
ex)
-
int num = 5; <- 00000101
-
num << 2; <- 00010100
-
결과값 : 20
-
왼쪽으로 n비트 이동한다는 것은 기존 값에 2n만큼 곱한다는 뜻
-
5 * 22 = 20
-
>> 연산자
-
오른쪽으로 비트를 이동하는 연산자
-
ex)
-
int num = 10; <- 00001010
-
num >> 2; <- 00000010
-
결과값 : 2
-
오른쪽으로 n비트 이동한다는 것은 기존 값에 2n만큼 나눈다는 뜻 (왜 소수점이 버려지나 했더니 int로 선언했음..)
-
10 / 22 = 2 <- int
-
>>> 연산자
-
>>이랑 동일하게 오른쪽으로 비트를 이동하는 연산자
-
왼쪽에 채워지는 비트값이 부호 비트와 상관없이 무조건 0이 되는 차이
-
ex)
-
int num = 10; <- 00001010
-
num >>> 2; <- 00000010
-
결과값 : 2
-
사실 뭐가 다른지 잘 모르겠다.
>>, >>> 연습
-6 : 11111010
-6 >>
11111110
00000001 + 1 = 00000010 <- 2 그래서 2인가?
연습
ex) -11
11은 00001011
반전 => 11110100
+1 -> 11110101
-11 >>2;
11110101을 두칸 옮기면 11111101 (1로 채워진다 가정하면)
11111101 <- 00000010 <- 00000011 <- 3 = -3
아마 음수는 1로 채워지는게 맞는 것 같다
그럼 -11을 >>> 하면?
>>>는 0으로 채운다 했으니 0으로 채워넣기
-11 >>>2 는 11110101 -> 00111101 이것도 반전 시켜야 하나? 일단 시키면 11000010 +1도 해보면 11000011임. 11000011 : 195
근데 막상 자바에 찍어보면 1073741821라는 난해한 숫자가 나옴
노가다로 1073741821를 16비트 2진법으로 바꾸면
해볼라했는데 16비트로도 불가능
32비트라고 치면
2의 0승 : 1
2의 1승 : 2
2의 2승 : 4
2의 3승 : 8
2의 4승 : 16
2의 5승 : 32
2의 6승 : 64
2의 7승 : 128
2의 8승 : 256
2의 9승 : 512
2의 10승 : 1024
2의 11승 : 2048
2의 12승 : 4096
2의 13승 : 8192
2의 14승 : 16384
2의 15승 : 32768
2의 16승 : 65536
2의 17승 : 131072
2의 18승 : 262144
2의 19승 : 524288
2의 20승 : 1048576
2의 21승 : 2097152
2의 22승 : 4194304
2의 23승 : 8388608
2의 24승 : 16777216
2의 25승 : 33554432
2의 26승 : 67108864
2의 27승 : 134217728
2의 28승 : 268435456
2의 29승 : 536870912
2의 30승 : 1073741824
2의 31승 : 2147483648
결론은 2의 30승에서 3을 뺀 값이니 32비트로 표현하면 00111111111111111111111111111100이다.
사실 졸면서 계산해서 맞는지 잘 모르겠다.
자료형의 크기(값의 범위) 순서
byte < short/char < int < long < float < double
연산자 우선순위
-
일차식 : () [] . 연산방향 →
-
단항 : ! ++ -- + - 연산방향 ←
-
산술 : % / 연산방향 →
-
산술 : + - 연산방향 →
-
비트 이동 : << >> 연산방향 →
-
관계 : < > <= >= 연산방향 →
-
관계 : == != 연산방향 →
-
비트 곱 : & 연산방향 →
-
비트 차 : ^ 연산방향 →
-
비트 합 : | 연산방향 →
-
논리 곱 : && 연산방향 →
-
논리 합 : || 연산방향 →
-
조건 : ?: 연산방향 →
-
대입 : = += -= *= %= /= 연산방향 ←
결론
비트 연산자를 처음 접해봐서 여러가지 방식으로 삽질을 했었다.. 좀 더 개념을 알게 되면 내용을 수정해야 할 것 같다.
참조 & 출저
Java 자료형