C language :: 2
C언어를 공부하며 진짜 시작이구나를 생각했던 구간
비트 단위 연산자가 필요한이유
비트는 0과 1을 저장할수 있는 공간이다 자료를 저장할수 있는 프로그램을 만들 때 비트 단위로 연산한다면 메모리를 많이 절약 할수 있다는 장점을 가지고 있다.
data = 0110 1010 //2진수
data = 0x5A 16진수 로 표현이 가능하다.
0 | X | 0 | 1 | 1 | 0 | 1 | 0 |
7번 비트 | 6번 비트 | 5번 비트 | 4번비트 | 3번 비트 | 2번 비트 | 1번 비트 | 0번 비트 |
오른쪽에서 윈쪽으로 갈수록 비트 번호가 커진다
시프트 연산자
시프트 연산자 <<, >> 는 변수의 값을 지정한 비트 수만큼 왼쪽 또는 오른쪽으로 비트를 이동시키는 기능을함
//오른쪽에서 왼쪽으로 이동
// 변수 << 이동할 비트 수
unsigned char data = 0x1A;
//이동전 : 0001 1010
data = data <<2;
//이동후 0110 1000
//왼쪽에서 오른쪽으로 이동
//변수 >> 이동할 비트 수
unsigned char data = 0x1A;
//이동전 0001 1010
data = data >> 2;
//이동후 0000 0110
이동한 비트들이 메모리 공간의 크기를 벗어나면 해당비트들은 사라지고 비트가 이동한 빈자리에는 0이 채워집니다.
비트가 왼쪽으로 이동해서 사라지는것을 오버플로우(Overflow)라고 부르고
오른쪽에서 이동해서 사라지는것을 언더플로우(Underflow)라고 부릅니다.
<< *2 /2>>
10진수 | 16 | 8 | 4 | 2 | 1 |
2진수 | 0001 0000 | 0000 1000 | 0000 0100 | 0000 0010 | 0000 0001 |
<<연산을 사용하여 n개의 비트를 오른쪽에서 왼쪽으로 이동하면 2n을 곱한 것과 같고
>>연산을 사용하여 n개의 비트를 왼쪽에서 오른쪽으로 이동하면 2n을 나눈것과 동일하다 .
즉 data = data <<3은 data = data*2의3승 과 같다는 뜻이고 data = data >>2 는 data = data/2의2승과 같다
시프트 연산자 사용시 주의할점
시프트 연산자의 우선순위가 + 덧셈 연산자보다 낮다 그래서 곱셈 나눗셈 로 이루어진 수식을 그대로 사용할 경우 잘못된 결과가 나올수 있다. 이문제를 해결할려면 괗로를 이용하여 결과값을 도출하면 된다.
비트 연산자
비트 연산자는 비트 단위로 AND(&), OR(|), XOR(^), NOT(~) 연산을 수행합니다.
C language :: 1 장 참조
AND(&)연산
두 값을 비트 단위로 AND 연산을 수행
0000 1111(0x0F)
&0011 1100(0x3C)
---------------
0000 1100(0x0C)
OR(|)연산
두 값을 비트 단위로 OR연산을 수행
0000 1111(0x0F)
|0011 1100(0x3C)
----------------
0011 1111(0x3F)
XOR(^) 연산
두 값을 비트 단위로 XOR연산을 수행
0000 1111(0x0F)
^0011 1100(0x3C)
----------------
0011 0011(0x33)
NOT(~) 연산
각 비트의 값을 반전 시키는 작업을 수행
~0000 1111(0x0F)
----------------
1111 0000(0xF0)
지정한 비트를 0으로 설정하기
AND 연산자 &을 사용하면 된다.
???? ???? //?는 0,1인지 알수없음
&1111 1011 // 2번 비트만 0으로 설정함
---------
???? ?0?? //2번 비트만 0으로 바뀜
임의의 비트를 1로 설정할수있습니다.
0x04를 직접 명시하지 않고 2번비트라는 정보만 가지고 만들어보면 ...
unsigned char lpam_state; //lamp_state 에 어떤값이 있는지 알 수 없음
unsigned char bit_num = 2; // 1로 만들 비트 번호
unsigned char mask = 0x01 << bit_num; //0x04
lamp_state = lamp_state | mask // lamp_state의 2번 비트만 1로 변경
이를 함수로 만들어보면
#include <stdio.h>
unsigned char SetBit(unsigned char dest_data, unsigned char bit_num)
{
if (bit_num < 8) dest_data = dest_data | (0x01 << bit_num);
return dest_data;
}
void main()
{
unsigned char lamp_state = 0x77; /* 0x77 → 0111 0111 */
printf("%X->", lamp_state); /* 변경 전 값 출력 */
/* lamp_state 변수의 3번째 비트를 1로 설정 */
lamp_state = SetBit(lamp_state, 3); /* 0x7F → 0111 1111 */
printf("%X\n", lamp_state); /* 변경 후 값 출력 */
}
이러한 방법을 통해 원하는 비트의값 , 보수이용, 데이터 암호화 등등 가능하다
1장보단 어렵지만 아직할만하다