<결과>
255
127
0
0
127
254
책에 보니까 이번건 잘 모르면 건너뛰라고 한다. C언어에 실력이 충분히 붙고 나서 봐도 늦지 않다고 한다.
하다가 머리아플거 같으면 그냥 넘어가고 나는 정말 잘 할 수 있다고 생각하면 이해해보자.
이번 예제를 이해하려면 2진수와 16진수를 알아야 한다.
2진수랑 16진수 이런걸 알면 좀 밑으로 내려가자.
----------------------------------------------------------------------------------------------------------------------------------------------------------
2진수 16진수 모르는사람만 읽으시구 알면 밑으로 가세요
사람은 기본적으로 10진수를 가장 많이 사용한다. 돈의 단위, 물건의 갯수 이런건 10진수로 사용한다.
근데 컴퓨터는 2진수밖에 모른다. 0이랑 1밖에 모른다. 위의 예제에 있는 255는 2진수로 1111 1111이다.
10진수로 숫자를 센다고 생각 해 보자.
0부터 9까지 센다. 그다음 자리올림이 발생했으니 1을 써놓고 뒤에 0~9까지 센다.
그다음 또 자리올림이 발생하니까 2를 써놓고 0~9까지 쓴다.
이렇게 반복해서 99까지 가면 또 자리올림이 발생하고 3자리 숫자가 된다.
이런식으로 반복한다.
2진수도 마찬가지다.
0~1을 세고 자리올림이 발생한다. 그럼 10이 된다.
그 다음 숫자는 11이고 그다음은 자리올림이 발생하니까 100으로 적는다.
101 -> 110 -> 111 -> 1000... 이런식이다.
근데 사람한테 2진수를 읽어라카면 바로 못읽는다. 숫자가 너무 많고 일반적으로 잘 사용하지 않기 때문이다.
그래서 16진수라는게 있다. 얘는 0~F 까지 쓴다.
A가 10이고 B가 11이고 C가 12 이고... 이런식이다.
이렇게 쓰면 알아보기가 편해진다. 보통 4자리씩 끊어서 읽는다.
위에 예제를 한 번 보자. 0x7F 라고 적혀있다. 0x는 그냥 얘는 16진수에요 라고 알려주는 친구다.
7F부분이 우리가 읽어야 할 숫자다.
7을 2진수로 표시하면 0111 이고 F를 2진수로 표시하면 1111 이다. 이걸 합치면 0111 1111 이다.
엄청 편하지 않나?
8진수도 있는데 여기선 굳이 쓸 필요는 없을 것 같다. 8진수도 똑같다. 0~7까지 센다.
----------------------------------------------------------------------------------------------------------------------------------------------------------
8줄 - printf("%d\n", ch & mask);
ch & mask 이부분을 알아야 한다.
ch와 mask를 2진수로 바꾼다음 AND 연산한다. 저번에 &&을 배운거랑 비슷하다.
ch 를 2진수로 하면 1111 1111 이고 mask를 2진수로 하면
0111 1111 이다.
이걸 and하면------------------------------
0111 1111
이 된다.
%d 로 출력해야 하니까 127이 나온다.
9줄 - printf("%d\n", (char)~ch);
이번엔 ~ 라는게 나온다. 이거는 NOT이라고 생각하자.
모든 비트를 반전시킨다.
ch를 2진수로 표현하면 1111 1111 인데 모두 반대로 표현하니까 0000 0000 이 된다.
10진수로 표현하면 0 이다.
10줄 - printf("%d\n", ch ^ ch);
이번엔 ^ 라는 친구가 나왔다. 이거는 XOR이라고 생각하자.
둘이 비교했을 때 숫자가 같으면 0이고 숫자가 다르면 1이다.
ch ^ ch 이니까 1111 1111
1111 1111
--------------------------------------
0000 0000
이 된다.
10진수로는 0 이다.
11줄 - printf("%d\n", ch >> 1);
<<, >> 이건 시프트 연산이라고 하는거다.
ch >> 1 이라고 적혀있다. 이거는 오른쪽으로 1칸 밀어라 라고 생각하자.
무슨 말이냐면
이런식이다.
그럼 빈자리가 하나 생기고 1이 밖으로 튀어 나간건 어떻게 처리하나요?
빈자리에는 0이 채워지고 튀어나간 1은 버린다.
그래서 0111 1111 이 된다.
10진수로는 127이다.
mask 부분은 << 인데 이건 왼쪽으로 옮기는거다. 이거랑 똑같다.
근데 여기서는 unsigned char 즉 부호가 없는 거라서 0을 채웠지만
만약에 부호가 있는걸 시프트 연산할 땐 좀 다르다. 무작정 0을 채우는게 아니라 부호비트를 채운다.
이건 나중에 또 설명할 날이 오겠지??
지금은 그냥 그렇구나 하고 넘어가자.
'c기초' 카테고리의 다른 글
031. sizeof 연산자 이해하기 (0) | 2020.03.19 |
---|---|
030. 캐스트 연산자 이해하기 (0) | 2020.03.18 |
028. 쉼표 연산자 이해하기 (,) (0) | 2020.03.18 |
027. 조건 연산자 이해하기 (?:) (0) | 2020.03.18 |
026. 논리 연산자 이해하기 (||, &&, !) (0) | 2020.03.18 |