저번 포스트에 앞내용을 그대로 가져오겠습니다.
C언어 연산자.
C연어 연산자는 C언어의 아주 기초적인 내용입니다.
아주 기초적이기 때문에 소홀히 하기 쉬운 부분이기도 합니다.
C언어에서 연산자가 상당히 많은 중요한 역할을 하고 있다 할 수 있지만, 주목받지 못하는 이유는 이해 하기가 너무 쉽고, 소프트웨어 관련 프로그램에서는 문법보다 많은 비중을 차지하지 못하기 때문입니다.
그럼에도 연산자를 알아야 하는 이유는, 당연히 C언어 코딩 과정이 게임을 만드든, 뭘 만드든 연산자와 함수를 통해서 이루어지기 때문이죠.
특히, 비트연산자는 하드웨어와 관련된 신호를 처리할 때 도움이 되는 개념으로 꼭 알아야 합니다.
※ 연산자 종류
분류 |
연산자 |
대입 연산자 |
= |
산술 연산자 |
+, -, *, /, % |
복합 대입 연산자 |
+=, -=, *=, /=, %= |
증감 연산자 |
++, -- |
관계 연산자 |
>, <, ==, !=, >=, <= |
논리 연산자 |
&&, ||, ! |
조건 연산자 |
? : |
비트 논리 연산자 |
&, |, ^, ~ |
비트 이동 연산자 |
>>, << |
대입 연산자 부터 조건 연산자 까지는 이전 포스팅에서 작성 되었습니다.
http://silisian.tistory.com/35
◎ 비트 논리 연산자
비트 논리 연산자는 총 &, |, ^, ~ 4개를 가지고있습니다.
비트 논리 연산자 |
구분 |
& |
비트 곱 (AND) |
| |
비트 합 (OR) |
^ |
베타적 비트 합 (XOR) |
~ |
비트 부정 (NOT) |
◎ 비트 곱은 비트 라는 것을 제외하고 생각하면 곱셈연산과 같습니다. 단, 비트별로 곱합니다.
◎ 비트 합은 비트 라는 것을 제외하고 생각하면 덧셈연산과 같습니다. 단, 비트별로 덧셈하며 결과값은 참/거짓(1/0)으로만 표현합니다.
◎ 베타적 비트 합은 비트별로 연산하며 같으면 거짓을 다르면 참을 반환합니다. 비트별 != 연산이라 생각하면 간단합니다.
◎ 비트 부정은 Not연산이며, 비트 보수 연산자라고 불리기도 합니다. 자기자신의 비트별 !연산이라 생각하면 간단합니다.
◎ 비트 곱 (AND)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | #include<stdio.h> void main() { /* 비트 곱은 비트별로 연산 한다느넛만 빼면 논리 곱과 똑같습니다. A(1100) 과 B(1010)을 비트 곱 한다 하면 차례대로 1&1 = 1 (1*1 = 1) 1&0 = 0 (1*0 = 0) 0&1 = 0 (0*1 = 0) 0&0 = 0 (0*0 = 0) 이 나오게 됩니다. 오른쪽 처럼 생각하면 간단하죠? */ //예제 소스 char Data = 0x86; //16진수인 0x86은 2진법으로 표현하면 1000 0110 입니다. char BitMask = 0xf2; //16진수인 0xf2는 2진법으로 표현하면 1111 0010 입니다. char Result = Data & Bitmask; //이 2개의 수를 비트곱 연산을 하게되면, 값은 1000 0010이 나오게됩니다. // 즉 0x82가 나오게 됩니다. /* 연산 1 & 1 = 1 0 & 1 = 0 0 & 1 = 0 0 & 1 = 0 0 & 0 = 0 1 & 0 = 0 1 & 1 = 1 0 & 0 = 0 */ } | cs |
◎ 비트 합 (OR)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | #include<stdio.h> void main() { /* 비트 합은 비트별로 연산 한다는것만 빼면 논리 합과 똑같습니다. A(1100) 과 B(1010)을 비트 합 한다 하면 차례대로 1|1 = 1 (1||1 = 1) 1|0 = 1 (1||0 = 1) 0|1 = 1 (0||1 = 1) 0|0 = 0 (0||0 = 0) 둘중 하나라고 비트값이 1 이면 1을 반환합니다. 논리연산자중 ||을 생각해서 둘중 하나라고 참이면 참을 반환한다. 라고 생각하면 간단합니다. */ //예제 소스 char Data = 0x86; //16진수인 0x86은 2진법으로 표현하면 1000 0110 입니다. char BitMask = 0xf2; //16진수인 0xf2는 2진법으로 표현하면 1111 0010 입니다. char Result = Data | Bitmask; //이 2개의 수를 비트곱 연산을 하게되면, 값은 1111 0110이 나오게됩니다. // 즉 0xf6가 나오게 됩니다. /* 연산 1 | 1 = 1 0 | 1 = 1 0 | 1 = 1 0 | 1 = 1 0 | 0 = 0 1 | 0 = 1 1 | 1 = 1 0 | 0 = 0 */ } | cs |
◎ 베타적 비트 합 (XOR)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | #include<stdio.h> void main() { /* 베타적 비트 합은 비트별로 연산 한다는것만 빼면 논리연산자중 != 과 똑같습니다. A(1100) 과 B(1010)을 베타적 비트 합 한다 하면 차례대로 1^1 = 1 (1!=1 = 0) 1^0 = 1 (1!=0 = 1) 0^1 = 1 (0!=1 = 1) 0^0 = 0 (0!=0 = 0) 두개의 값이 서로 다르다면 1 같으면 0을 반환합니다. 논리연산자중 !=을 생각해서 둘이 다르다면 참을 반환 한다고 생각하면 간단합니다. */ //예제 소스 char Data = 0x86; //16진수인 0x86은 2진법으로 표현하면 1000 0110 입니다. char BitMask = 0xf2; //16진수인 0xf2는 2진법으로 표현하면 1111 0010 입니다. char Result = Data ^ Bitmask; //이 2개의 수를 비트곱 연산을 하게되면, 값은 0111 0100이 나오게됩니다. // 즉 0x74가 나오게 됩니다. /* 연산 1 ^ 1 = 0 0 ^ 1 = 1 0 ^ 1 = 1 0 ^ 1 = 1 0 ^ 0 = 0 1 ^ 0 = 1 1 ^ 1 = 0 0 ^ 0 = 0 */ //여기서 특이한점은, 베타적 비트합을 2번 연산 하게되면 원래 값으로 돌아가게 됩니다. Result = Result ^ Bitmask; // (0111 0100) ^ (1111 0010) = 1000 0110 //이처럼 XOR 즉 베타적 비트 합은 암호화의 자주 사용 됩니다. } | cs |
◎ 비트 부정 (NOT)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | #include<stdio.h> void main() { /* 비트 부정은 자기자신의 비트별로 연산 한다는것만 빼면 논리연산자중 ! 과 똑같습니다. 논리연산자중 앞에 !을 붙이면 참과 거짓이 바뀌듯 비트값앞에 !을 붙이게되면 비트의 0과 1이 바뀌게 됩니다. 따라서 A(1100)를 ~A 한다 하면 차례대로 ~1 = 0 ~1 = 0 ~0 = 1 ~0 = 1 1은 0으로 0은 1로 연산하게 됩니다. */ //예제 소스 char Data = 0x86; //16진수인 0x86은 2진법으로 표현하면 1000 0110 입니다. char Result = ~Data; //Data를 부정(~) 하게되면 0111 1001이 됩니다. // 즉 0x79가 나오게 됩니다. /* 연산 ~1 = 0 ~0 = 1 ~0 = 1 ~0 = 1 ~0 = 1 ~1 = 0 ~1 = 0 ~0 = 1 */ } | cs |
◎ 비트 이동 연산자
비트 이동 연산자는 총 << 과 >> 가지고있습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | #include<stdio.h> void main() { /* 비트 이동 연산자는 비트의 위치를 왼쪽 또는 오른쪽으로 온긴다고 생각하면 됩니다. A(1101)를 B = A<<2; 라 하면 B의 값은 0100이 됩니다. A를 왼쪽으로 2번 쉬프트 하면 11 0100 이 됩니다. 하지만 범위를 초과한 비트는 버려지게 됩니다. 따라서 0100만 남아서 B의 값이 됩니다. ( A값은 변하지 않습니다. ) */ //예제 소스 char Data = 0x76; //16진수인 0x86은 2진법으로 표현하면 0111 0110 입니다. char Result01 = Data<<2; //Data를 <<2 하게되면 1101 1000이 됩니다. char Result02 = Data>>2; //Data를 >>2 하게되면 0001 1101이 됩니다. char Result03 = Data<<8; //Data를 <<8 하게되면 0000 0000이 됩니다. } | cs |
참고 자료 1 : https://ko.wikipedia.org/wiki/%EB%85%BC%EB%A6%AC_%EC%97%B0%EC%82%B0
참고 자료 2 : http://www.tipssoft.com/bulletin/board.php?bo_table=FAQ&wr_id=598
참고 자료 3 : https://msdn.microsoft.com/ko-kr/library/336xbhcz.aspx
'프로그래밍 > Language' 카테고리의 다른 글
try, throw, catch 를 이용한 예외 처리 방법 (0) | 2016.02.23 |
---|---|
포인터에 대하여 (0) | 2016.02.23 |
C언어 연산자에 대하여 (0) | 2016.02.23 |
상수란 무엇인가? (0) | 2016.02.22 |
변수란 무엇인가? (0) | 2016.02.22 |