1. 포인터와 역참조
int a = 10;
int *b = &a;
| a | 변수에 저장된 값 | 10 |
| &a | a의 주소 | 주소값 |
| b | a의 주소를 저장한 포인터 | &a |
| *b | b가 가리키는 곳의 값 | 10 |
핵심은 b와 a가 같은 것이 아니라, *b와 a가 같은 메모리 공간을 뜻한다는 것이다.
*b = 20;
printf("%d", a); // 20
*b를 변경하면 같은 공간을 사용하는 a도 변경된다.
기호의 문맥도 구분해야 한다.
- int *b: 포인터 선언
- *b: 역참조
- &a: 주소 얻기
- a & b: 비트 AND
원문의 ***b를 출력하면?은 문맥상 *b를 출력하면?의 오타다.
2. 배열과 포인터
int arr[3] = {10, 20, 30};
int *p = arr;
배열 이름 arr은 대부분의 식에서 첫 원소의 주소인 &arr[0]으로 변환된다.
arr[i] == *(arr + i)
p[i] == *(p + i)
| *p 또는 *(p+0) | 10 |
| *(p+1) | 20 |
| *(p+2) | 30 |
p+1은 주소를 1바이트 이동한다는 뜻이 아니다. 포인터가 가리키는 자료형 한 칸만큼 이동한다. int *p라면 다음 int 원소로 이동한다.
시험 함정:
*(p + 1) // 다음 원소의 값
*p + 1 // 현재 원소의 값에 1을 더함
또한 p++는 가능하지만 배열 이름 자체에 arr++는 사용할 수 없다.
3. 시프트·비트 연산자
| x << n | 왼쪽 시프트 | 양수 기준 x × 2ⁿ |
| x >> n | 오른쪽 시프트 | 양수 기준 x ÷ 2ⁿ의 몫 |
| & | AND | 둘 다 1이면 1 |
| | | OR | 하나라도 1이면 1 |
| ^ | XOR | 서로 다르면 1 |
| ~ | NOT | 모든 비트 반전 |
예시:
10 << 2 // 10 × 4 = 40
10 >> 2 // 10 ÷ 4의 몫 = 2
10 ^ 12 // 6
~10 // -11
NOT의 시험 공식:
~x = -(x + 1)
시프트의 곱셈·나눗셈 공식은 주로 양수이며 오버플로가 없는 문제에서 사용한다.
4. 연산자 우선순위
암기어는 최단산시관비논삼대콤이다.
- 최: 최우선 (), [], ., ->
- 단: 단항 !, ~, ++, --, sizeof, 형변환, 역참조
- 산: 산술 * / % → + -
- 시: 시프트 << >>
- 관: 관계 < <= > >= → == !=
- 비: 비트 & → ^ → |
- 논: 논리 && → ||
- 삼: 삼항 조건 ? 참 : 거짓
- 대: 대입 =, +=, -=
- 콤: 콤마 ,
단항·삼항·대입 연산자는 주로 오른쪽에서 왼쪽으로 결합한다.
전위와 후위
int a = 3;
int b = ++a; // a=4, b=4
전위는 증가한 값을 사용한다.
int a = 3;
int b = a++; // b=3, 이후 a=4
후위는 기존 값을 먼저 사용한 뒤 증가한다. 단순히 “무조건 줄 마지막에 증가한다”보다 식의 결과로 이전 값을 내놓는다고 이해하는 편이 정확하다.
5. n진수와 16진수
n진수를 10진수로 바꾸는 공식:
각 자릿수 × n의 자릿값을 모두 더한다.
예시:
1011₂ = 1×2³ + 0×2² + 1×2¹ + 1×2⁰ = 11
35₈ = 3×8¹ + 5×8⁰ = 29
1A₁₆ = 1×16¹ + 10×16⁰ = 26
16진수는 A=10부터 F=15까지 사용한다.
16진수 한 자리 = 2진수 4비트
0x35
3 → 0011
5 → 0101
0x35 → 0011 0101 → 53
4비트로 표현할 수 있는 경우가 2⁴=16개이므로 16진수 한 자리와 정확히 대응한다.
6. AND 마스킹
0x35 = 0011 0101
0x0F = 0000 1111
-----------
AND = 0000 0101 = 0x05
따라서:
0x35 & 0x0F // 결과 5
& 0x0F는 상위 4비트를 지우고 하위 4비트만 남기는 마스킹이다.
7. 형변환과 %x
(int)5.8 // 5
(int)-5.8 // -5
실수를 정수로 형변환하면 소수점 이하를 0 방향으로 버린다. 비트 연산자는 int만 가능한 것이 아니라 char, int, long, unsigned 등 정수형 자료형에 사용할 수 있고 실수형에는 직접 사용할 수 없다.
출력 서식:
- %d: 10진수
- %x: 소문자 16진수
- %X: 대문자 16진수
%x는 계산 결과를 바꾸는 연산자가 아니라, 같은 값을 16진수 모양으로 보여주는 출력 규칙이다.
시험 직전 10줄 암기
- &a는 주소, *p는 그 주소의 값
- int *p = &a이면 *p와 a는 같은 공간
- arr[i] == *(arr+i)
- p+1은 자료형 한 칸 이동
- << n은 양수 기준 ×2ⁿ
- >> n은 양수 기준 ÷2ⁿ의 몫
- XOR은 다르면 1
- ~x = -(x+1)
- 16진수 한 자리 = 2진수 4비트
- 우선순위는 최단산시관비논삼대콤