20140311 (비트연산자, 상수, 변수, const, sizeof)
17일차
-------------
비트연산자
-------------
비트 연산자 종류는
| OR 조건 하나가 참일 때 참
& AND 조건 둘 다 참일 때 참
^ XOR 두 조건이 서로 반대일 때 참
~ TILDE 비트 반전
<< LEFT SHIFT 왼쪽으로 비트 이동
>> RIGHT SHIFT 오른쪽으로 비트 이동
가 있다.
아래 예제 소스코드를 보자.
#include <stdio.h>
int main()
{
int iNum1;
int iNum2;
int iNum3;
// OR
iNum1 = 0xB;
iNum2 = 0x4;
iNum3 = iNum1 | iNum2;
printf("OR : 0x%X\n\n", iNum3);
// AND
iNum1 = 0xB;
iNum2 = 0x4;
iNum3 = iNum1 & iNum2;
printf("AND : 0x%X\n\n", iNum3);
// TILDE
iNum1 = 0xFFFFFFF0;
iNum2 = !iNum1;
iNum3 = ~iNum1;
printf("iNum1 : 0x%08X\n", iNum1);
printf("iNum2 : 0x%08X\n", iNum2);
printf("iNum3 : 0x%08X\n\n", iNum3);
// XOR
iNum1 = 0xB;
iNum2 = 0x6;
iNum3 = iNum1 ^ iNum2;
printf("XOR : 0x%X\n\n", iNum3);
// right SHIFT
iNum1 = 0x18 >> 1;
iNum2 = iNum1 >> 1;
iNum3 = iNum2 >> 2;
printf("iNum1 : 0x%X\n", iNum1);
printf("iNum2 : 0x%X\n", iNum2);
printf("iNum3 : 0x%X\n\n", iNum3);
// left SHIFT
iNum3 = iNum3 << 3;
printf("iNum3 : 0x%X\n", iNum3);
return 0;
}
실행 결과
결과물에 위에 iNum2 : 0x00000000은 ~와 !가 헷갈려서
넣어서 비교해 보았다.
여기서 SHIFT 연산자를 좀 자세히 보기로 하였다.
아래 소스코드
#include <stdio.h>
int main()
{
signed int iNum;
unsigned int uiNum;
//
iNum = 0xFFFFFFFF;
uiNum = 0xFFFFFFFF;
printf("1\n");
printf("iNum : 0x%X\n", iNum);
printf("uiNum : 0x%X\n", uiNum);
printf(" >> 1\n");
iNum = iNum >> 1;
uiNum = uiNum >> 1;
printf("iNum : 0x%X\n", iNum);
printf("uiNum : 0x%X\n", uiNum);
//
iNum = 0x82345678;
uiNum = 0x82345678;
printf("\n2\n");
printf("iNum : 0x%X\n", iNum);
printf("uiNum : 0x%X\n", uiNum);
printf(" >> 1\n");
iNum = iNum >> 1;
uiNum = uiNum >> 1;
printf("iNum : 0x%X\n", iNum);
printf("uiNum : 0x%X\n", uiNum);
//
iNum = 0x72345678;
uiNum = 0x72345678;
printf("\n3\n");
printf("iNum : 0x%X\n", iNum);
printf("uiNum : 0x%X\n", uiNum);
printf(" >> 1\n");
iNum = iNum >> 1;
uiNum = uiNum >> 1;
printf("iNum : 0x%X\n", iNum);
printf("uiNum : 0x%X\n", uiNum);
//
iNum = 0x72345678;
uiNum = 0x72345678;
printf("\n4\n");
printf("iNum : 0x%X\n", iNum);
printf("uiNum : 0x%X\n", uiNum);
printf(" << 1\n");
iNum = iNum << 1;
uiNum = uiNum << 1;
printf("iNum : 0x%X\n", iNum);
printf("uiNum : 0x%X\n", uiNum);
//
iNum = 0x82345678;
uiNum = 0x82345678;
printf("\n5\n");
printf("iNum : 0x%X\n", iNum);
printf("uiNum : 0x%X\n", uiNum);
printf(" << 1\n");
iNum = iNum << 1;
uiNum = uiNum << 1;
printf("iNum : 0x%X\n", iNum);
printf("uiNum : 0x%X\n", uiNum);
return 0;
}
실행 결과
여기서 변수 앞에 signed, unsigned를 붙여서 연산한 결과가
다르게 나온다는 것을 볼 수 있다.
>> 오른쪽 SHIFT로 비트를 움직일 경우
1번과 2번의 결과를 통해
signed는 맨 앞에 부호비트로 인식?해서 맨 앞자리는 계속 1(음수)을 채워 넣고
unsigned는 명령하는 대로 움직이는 것을 볼 수 있다.
하지만 3번과 4번, 5번을 통해
signed의 맨 앞자리가 0일 경우(양수) unsigned와 같은 결과를 보고
<< 왼쪽 SHIFT로 비트를 움직일 경우
둘 다 명령처럼 움직이는 것을 볼 수 있다.
* 따라서 SHIFT연산을 할 경우 원하는 값대로 나오게 하려면
unsigned를 붙여야 한다. 또 컴퓨터 내에서 unsigned가 더 빠르다
-------------------
상수와 변수, const
-------------------
const는 변수를 상수화 시키는 것이다.
오직 읽기만 가능하기에 반드시 선언시에 초기화를 해야한다.
아래는 const상수 실습 소스코드.
#include <stdio.h>
int main()
{
int iNum = 3;
const int ciNum = 100;
iNum = 100;
// ciNum = 1000;
printf("%d\n", ciNum);
return 0;
}
위에 ciNum = 1000;을 넣으면 l-value Error가 뜬다.
iNum = 100;
=을 중심으로 왼쪽은 l-value (Left Value),
오른쪽은 r-value (Right Value)라고 부른다.
-------
sizeof
-------
변수나 상수 등 크기를 측량하는 연산자.
지금까지 sizeof()가 뒤에 괄호가 붙으니 함수인지 알았는데
연산자였다.... 괄호는 우선순위만 정해주는 역할이었다.. 충격..
아래는 실습 소스코드
#include <stdio.h>
int main()
{
int iNum;
printf("char : %d\n", sizeof(char));
printf("short : %d\n", sizeof(short));
printf("int : %d\n", sizeof(int));
printf("long : %d\n", sizeof(long));
printf("long long : %d\n", sizeof(long long));
printf("float : %d\n", sizeof(float));
printf("double : %d\n", sizeof(double));
printf("long double : %d\n", sizeof(long double));
// printf("sizeof 3.5 : %d\n", sizeof 3.5 );
// printf("sizeof iNum + 3 : %d\n", sizeof iNum + 3);
return 0;
}
출력 화면
왼쪽은 MS-DOS VC++로 실행한 결과이고
오른쪽은 Linux gcc에서 실행한 결과이다.
변수의 크기는 컴파일러 마다 다르기 때문에
새로운 컴파일러를 사용시 꼭 확인해야 한다.
그리고 아래는 sizeof가 함수가 아니라 연산자라는 것을 확인한 것이다
위에 소스에서 주석 처리한 부분을 실행한 결과다.
결과 화면과 같이 sizeof 는 연산자였다.......
그리고 실수를 넣었을 때에 컴파일러 마다 float일지 double형일지는
이것도 확인해 봐야 한다고 한다.