프롤로그
ELITE HACKER Bootcamp 3rd 2주차 수업 공부 내용
aws 우분투 서버 하나 파서 연습
연산자 종류, 산술연산자, 비트연산자, 논리연산자, 증감연산자, 형변환
연산자
연산자란 값이나 변수에 특정 작업을 수행하는 데 사용되는 기호를 말한다. 흔히 우리가 아는 사칙연산 +, - 이런 것들도 값 또는 변수에 "특정 작업"을 수행하기에 이 또한 포함된다.
다양한 연산자가 있는데 아래 쭉 살펴보자.
산술연산자
산술연산자, 사칙연산이라고 생각을 하면 된다. 우리가 아는 그 사칙연산 +-*/ 맞다.
+ | 더하기 | a+b |
- | 빼기 | a-b |
* | 곱하기 | a*b |
/ | 나눗셈 (몫) | a / b |
% | 나눗셈 (나머지) , 모듈러라고도 함 | a % b |
보면은 나눗셈이 / 도 있고 %도 있는데, 아래 코드로 확인해보자.
#include <stdio.h>
int main() {
int a = 3;
int b = 2;
printf("a / b : %d\na %% b : %d\n", a / b, a % b);
return 0;
}
아 그러면, 정수끼리 나눗셈을 계산하면 결국엔 몫과 나머지로 나뉘어지니까 무조건 정수인건가?, 완전한 값을 나오게 하려면 어떻게 해야할까?
정수와 정수를 연산을 진행하면 결과값은 항상 정수이다. 그럼 실수와 실수 연산을 진행하면 결과값은 항상 실수이다. 실수와 정수를 계산하면? 정수보다 실수의 값의 범위가 더 크기 때문에 실수로 전환되어 계산한다.
그래서 a를 float로 변환시키고 다시 연산을 진행하면 실수값이 나오게 된다.
#include <stdio.h>
int main() {
int a = 3;
int b = 2;
printf("정수 연산 : %d\n", a/b);
printf("실수 연산 : %f\n", (float)a/b);
return 0;
}
(float)a/b 로 a의 값을 실수로 바꿔주었는데, 저렇게 하는 것을 형변환이라고 한다.
아까 정수 와 정수의 연산은 정수가 나오고, 실수와 실수 연산은 실수가 나온다고 했다. 그럼 다시 정수와 실수를 연산했을 때 결과값은 뭐가나오느냐?
#include <stdio.h>
int main() {
double a = 3;
int b = 2;
// printf("정수형 출력 : %d\n", a+b);
printf("실수형 출력 : %f\n", a+b);
return 0;
}
저거 주석처리된 부분 해제하고 해보면?
결과값은 큰 double에 따라가기에 아예 컴파일 자체가 안 되는 것을 알 수 있다.
다시 주석처리 한 후에 컴파일 하면 정상적으로 나온다.
비트연산자
산술연산자는 값과 값의 비교였다면, 이번엔 비트와 비트간의 비교를 하여서 계산을 한다. 비트라는 건 0과 1로 이루어져있는데, 이들의 연산을 한다? 저수준이라는 것이다. 저수준과 고수준에 차이는 컴퓨터와 더 가까우면 저수준, 사람과 더 가까우면 고수준 느낌.
그래서 어셈블리는 중간수준 언어라고도 불린다.
& | 비트 AND | a & b |
| | 비트 OR | a | b |
^ | 비트 XOR | a ^ b |
~ | 비트 Not | ~a |
<< | 비트 왼쪽 시프트 | a << 2 |
>> | 비트 오른쪽 시프트 | a >> 2 |
비트 연산 예시를 좀 들겠다.
7과 4가지고 해볼건데
int a = 7; //111
int b = 4; //100
이렇게 7은 비트로 표현하면 111이고, 4는 000이다.
AND 연산은 비트 둘 다 1인 경우에 1을 연산결과로 내놓는다. 그래서
111
100
ㅡㅡㅡㅡ
100 -> 4
이런 연산 결과로 4가 나올 것이다.
#include <stdio.h>
int main(){
int a = 7; //111
int b = 4; //100
printf("%d\n", a & b); //4
return 0;
}
잘 나온 것이 확인되었다.
or연산은 두 비트 중에 하나만 1이어도 1로 켜지는 연산과정을 가진다.
//OR 연산
111 -> 7
100 -> 4
ㅡㅡㅡㅡㅡㅡㅡㅡ
111 -> 7
xor 연산은 두 비트중에 하나만, 세 개 이상이 계산된다면? 해당 자릿수에 총 1의 개수가 홀수인 경우에 연산결과가 1로 반환된다.
//XOR 연산
111 -> 7
100 -> 4
ㅡㅡㅡㅡㅡㅡㅡ
011 -> 3
그래서 and, or, xor 연산 결과 다 확인해보면
이렇게 결과값이 나오는 것을 확인하였다. and는 자릿수에 있는 해당 비트가 모두 1일때, or은 하나만이라도 켜져있으면 1, xor은 해당 자릿수의 1의 개수가 홀수일 경우에는 1
Not연산인 ~ 이거 같은 경우에는 ~b 를 해주게 된다면 기존 100의 비트가 1은 0이 되고, 0은 1이되어서 011로 바뀌게 된다. 그럼 3이라는 값이 나오게 된다. 잘 이해가 안 되다면 이진수에 대해서 잘 공부해보길 바란다.
다음은 시프트 레지스터 <<, >> 이거이다. 이게 지금은 왜 쓰일지 잘 모를 수 있는데, 후반이라던지 뭐 컴구조 같은 곳에서 좀 많이 쓰인다. 알아두면 좋음.
7 << 2 //111 << 2 비트를 왼쪽으로 두 칸 이동
28 //11100 //4 맨 뒤에 0이 채워지면서 왼쪽으로 2칸 이동
이렇게 << 또는 >> 뒤에 있는 숫자만큼 비트를 이동시킨다.
#include <stdio.h>
int main() {
int a = 7;
printf("%d\n", a<<2);
return 0;
}
2칸 이동을 했는데 7에다가 2^2 를 곱한 값이 나온다. 즉 한 칸 시프트 될 때마다 *2가 된다는 의미
#include <stdio.h>
int main() {
int a = 7;
printf("%d\n", a>>2);
return 0;
}
반대로 오른쪽 시프트를 하면?
/2가 된다. 이런 느낌으로 사용한다.
논리연산자
논리적인 판단을 수행하여 참(1) 또는 거짓(0)을 반환하는데, 대충 이렇다.
&& | 논리 AND | a && b |
|| | 논리 OR | a || b |
! | 논리 NOT | !a |
논리 연산자는 진짜 논리적으로 계산한다. a도 참이고 b도 참인 경우 &&로 논리적 판단해서 참 또는 거짓을 리턴시키는 느낌인데
이게 a = 0, 즉 0이라는 정수값이 들어가있으면 false로 인식되고, a = 1이상의 숫자가 들어가있으면 참으로 인식되고 이런 건 알아야한다.
관계연산자
이건...알지?
>=. <=, <, > , !=, ==... 넘어간다. 대충 맞으면 참(1), 아니면 거짓 (0) 반환한다.
대입연산자
아까 위에서 산술연산자의 생략버전이라고 생각하면 된다.
= | 대입 | a = b |
+= | 덧셈 후 대입 | a += b |
-= | 뺄셈 후 대입 | a -= b |
*= | 곱셈 후 대입 | a *= b |
/= | 나눗셈 후 대입 | a /= b |
%= | 나머지 연산 후 대입 | a %= b |
아까 a = a+b라고 되어있으면, a에다가 그냥 b더하는 거 a +=b로 축약한다고 보면 되는 것이다.
증감연산자
근데 a = a+1 이라던지 a +=1이라던지 이것조차 쓰기 귀찮을 때 증감연산자를 쓴다. a++또는 ++a; 이렇게 그냥 ++로 축약시켜버리는 거다.
#include <stdio.h>
int main() {
int a = 1;
printf("a : %d\n", a++);
a = 1;
printf("a : %d\n", ++a);
return 0;
}
++a와 a++의 차이를 알아야한다. ++a는 +1 연산을 먼저 해준 다음에 a값을 처리하라이고
a++은 출력부터 한 다음에 +1을 해줘라 이런 느낌이다.
기타연산자
- sizeof: 자료형 또는 변수의 크기를 반환.
- 형 변환 연산자 (Type Casting): 자료형을 명시적으로 변환할 때 사용
- 콤마 연산자 (,): 여러 표현식을 하나의 문장으로 연결하며, 가장 오른쪽의 표현식의 결과를 반환
형 변환(TypeCasting)
한 자료형의 값을 다른 자료형으로 변환하는 과정. 암시적(Implicit)과 명시적(Explicit) 두 가지로 나눌 수 있다.
암시적 형변환
컴파일러가 자동으로 형변환 시켜준다.
앞에 자료형이 뒤의 자료형보다 큰 경우, 즉 뒤의 자료형이 앞의 자료형보다 작은 경우에 발생하는데,
int a = 10;
double b = a; // int형 a가 자동으로 double형으로 변환
printf("%f\n", b); // 출력: 10.000000
자동적으로 형태가 변경된다. 데이터 손실이 거의없고 컴파일러가 자동수행!
명시적 형변환
프로그래머가 직접 형 변환을 해주는 경우이다.
double num = 3.14;
int intNum = (int)num; // double형을 int형으로 명시적으로 변환
printf("%d\n", intNum); // 출력: 3 (소수점 이하 버려짐)
실수에서 정수로 값이 바뀌면서 .14 값이 손실되었다.
에필로그
어렵다
'KnockOn' 카테고리의 다른 글
[KnockOn] Linux/Ubuntu C언어 조건문, 반복문 (2) | 2024.11.15 |
---|---|
[KnockOn] Linux/Ubuntu C언어 입출력함수 (1) | 2024.11.14 |
[KnockOn] Linux/Ubuntu C언어 자료형 (0) | 2024.11.12 |
[KnockOn] Linux/Ubuntu C언어 및 컴파일 (0) | 2024.11.11 |
[KnockOn] Linux/Ubuntu SSH, NC (0) | 2024.11.07 |