728x90
반응형

* 대충 1억번의 연산은 1초정도 걸린다.
* 매크로 함수에서는 사칙연산을 고려해서 각 변수에 괄호를 꼭 씌워주자.
* Left Shift 연산자는 2의 거듭 제곱을 구할때 편함 ( 1>>i )
* 정수에 not(!) 연산자를 사용하는 경우에는,
- 숫자가 0인경우 -> 1을 반환한다.
- 숫자가 1이 아닌 경우 -> 0을 반환한다.
예시:
int a = 0;
int b = 1;
int c = 10;
printf("%d",!a); // 1 출력
printf("%d",!b); // 0 출력
printf("%d",!c); // 0 출력
1) typedef(ll), 매크로, 상수, 오버플로우, min/max 갱신
코드
#include <stdio.h>
// 타입 재정의
typedef long long ll;
// 매크로 함수 (괄호 중요)
#define MULTIPLY(x, y) ((x) * (y))
// 상수
#define MAX (100)
#define INF (0x7fff0000) // 충분히 큰 값(최솟값 초기화에 자주 사용)
#define LEFT (0)
#define RIGHT (1)
#define UP (2)
#define DOWN (3)
int arr[MAX];
int MAP[MAX][MAX];
int main()
{
ll big = 0; // ll = long long(보통 64비트 정수)
int a = 5;
int b = 3;
int c = MULTIPLY(a + b, a + b);
printf("c = %d\n", c);
int direction = LEFT;
// 방향 값 비교 예시(여기서는 아무 것도 안 하고 비교만 함)
if (direction == LEFT) { /* ... */ }
else if (direction == RIGHT){ /* ... */ }
else if (direction == UP) { /* ... */ }
else if (direction == DOWN) { /* ... */ }
printf("0x7fff0000 : %d\n", 0x7fff0000);
int maxInt = 2147483647; // int 최대값(대부분 환경)
int maxInt16 = 0x7fffffff;
printf("maxInt : %d\n", maxInt);
printf("maxInt16 : %d\n", maxInt16);
printf("maxInt + 1 : %d\n", maxInt + 1);
printf("maxInt16 + 1 : %d\n", maxInt16 + 1);
int d = 1, e = 10, f = 5;
int min = INF;
if (d < min) min = d;
if (e < min) min = e;
if (f < min) min = f;
int max = -INF;
if (max < d) max = d;
if (max < e) max = e;
if (max < f) max = f;
printf("min %d, max %d\n", min, max);
return 0;
}
출력(예시)
(일반적인 32비트 int 환경에서 보이는 흔한 결과)
c = 64
0x7fff0000 : 2147418112
maxInt : 2147483647
maxInt16 : 2147483647
maxInt + 1 : -2147483648
maxInt16 + 1 : -2147483648
min 1, max 10
설명
- typedef long long ll;
- ll은 long long의 별칭. 큰 정수(보통 64비트)를 짧게 쓰려고 만든다.
- #define MULTIPLY(x,y)
- 매크로는 “텍스트 치환”이라서 괄호를 충분히 써야 안전하다.
- MULTIPLY(a+b, a+b)는 실제로 ((a+b)*(a+b))로 치환되어 8*8=64.
- maxInt + 1
- int 최댓값에서 1을 더해 오버플로우가 난다.
- 많은 환경에서 -2147483648로 보이지만, C 표준에서는 signed 오버플로우가 “정의되지 않은 동작”이라 결과를 100% 보장하진 않는다.
- INF로 min 초기화 / -INF로 max 초기화
- 반복 비교로 min/max 구하는 가장 기본 패턴.
2) 구조체(struct) 반환: 좌표/두 값 묶어서 리턴
코드 (C 버전)
#include <stdio.h>
typedef struct RC {
int r;
int c;
} RC;
RC getValue(void)
{
RC ret = { 5, 3 }; // 구조체 초기화
return ret; // 구조체 통째로 반환
}
int main(void)
{
RC tmp = getValue();
printf("%d %d\n", tmp.r, tmp.c);
return 0;
}
출력
5 3
설명
- 구조체는 관련된 값을 묶어서 관리하기 좋다. (예: 좌표 r,c)
- 함수에서 구조체를 반환하면 tmp.r, tmp.c로 접근 가능하다.
- C++에서는 return {5,3}; 같은 형태도 가능하지만, C는 보통 RC ret = {5,3}; return ret; 패턴을 쓴다.
3) 후위 증가(i++) vs 전위 증가(++i)
코드
#include <stdio.h>
int a[10];
int b[10];
int main()
{
for (int i = 1; i <= 10; i++) printf("%d ", i);
putchar('\n');
for (int i = 1; i <= 10; ++i) printf("%d ", i);
putchar('\n');
int aIndex, bIndex;
aIndex = bIndex = 0;
for (int i = 1; i <= 10; i++)
{
if (i % 2 == 0)
{
// 후위 증가: 현재 인덱스에 넣고, 그 다음 증가
a[aIndex++] = i;
// 전위 증가: 먼저 증가하고, 증가된 인덱스에 넣음
b[++bIndex] = i;
}
}
for (int i = 0; i < 10; i++) printf("%d ", a[i]);
putchar('\n');
for (int i = 0; i < 10; i++) printf("%d ", b[i]);
putchar('\n');
return 0;
}
출력(예시)
초기값이 전역 배열이라 0으로 채워진 상태에서 시작함.
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
2 4 6 8 10 0 0 0 0 0
0 2 4 6 8 10 0 0 0 0
설명
- a[aIndex++] = i;
- aIndex가 0일 때 a[0]=2 저장 후 aIndex가 1이 됨.
- 그래서 a는 [2,4,6,8,10,...] 형태로 앞에서부터 채워짐.
- b[++bIndex] = i;
- bIndex가 0일 때 먼저 1이 되고 b[1]=2가 됨.
- 그래서 b[0]은 비어 있고, 값이 1칸 밀려서 저장됨.
- 결론: 인덱스로 값을 넣는 상황에서는 후위/전위 차이가 결과를 바꾼다.
4) 삼항 연산자: 조건에 따라 값 선택
코드
#include <stdio.h>
int abs(int x)
{
return (x > 0) ? x : -x;
}
int main()
{
printf("abs(3) = %d\n", abs(3));
printf("abs(-3) = %d\n", abs(-3));
return 0;
}
출력
abs(3) = 3
abs(-3) = 3
설명
- (조건) ? 참일때값 : 거짓일때값
- if-else를 한 줄로 줄이는 표현.
- 단, 너무 복잡한 조건을 삼항으로 중첩하면 가독성이 떨어진다.
5) 나머지 연산자(%)로 방향 회전 구현
코드
#include <stdio.h>
#define NORTH (0)
#define WEST (1)
#define SOUTH (2)
#define EAST (3)
int main()
{
int direction = NORTH;
// 반시계: 0->1->2->3->0
direction = (direction + 1) % 4;
// 시계: 0->3->2->1->0
direction = (direction - 1 + 4) % 4; // 언어마다 구현되는 특징이 다르므로 안전하게 +4를 하자.
printf("counter clockwise\n");
for (int i = 0; i < 4; i++)
printf("%d -> %d\n", i, (i + 1) % 4);
putchar('\n');
printf("clockwise\n");
for (int i = 0; i < 4; i++)
printf("%d -> %d\n", i, (i - 1 + 4) % 4);
putchar('\n');
return 0;
}출력
counter clockwise
0 -> 1
1 -> 2
2 -> 3
3 -> 0
clockwise
0 -> 3
1 -> 0
2 -> 1
3 -> 2
설명
- % 4를 쓰면 값이 항상 0~3 범위로 유지된다.
- 시계 방향은 음수가 나올 수 있어 +4를 더해 안전하게 만든 뒤 % 4.
6) NOT 연산자(!)와 !!로 0/1 정규화
코드
#include <stdio.h>
int arr[10]; // 전역 배열 -> 기본값 0
int main()
{
int a = 0;
int b = -1243;
int c = 123;
printf("!a : %d\n", !a);
printf("!!a : %d\n", !!a);
printf("!b : %d\n", !b);
printf("!!b : %d\n", !!b);
printf("!c : %d\n", !c);
printf("!!c : %d\n", !!c);
int count;
// 배열에서 0인 값 count (arr가 전부 0이므로 결과는 10)
count = 0;
for (int i = 0; i < 10; i++) count += !arr[i];
printf("zero count = %d\n", count);
// 배열에서 0이 아닌 값 count (전부 0이므로 결과는 0)
count = 0;
for (int i = 0; i < 10; i++) count += !!arr[i];
printf("non-zero count = %d\n", count);
return 0;
}
출력
!a : 1
!!a : 0
!b : 0
!!b : 1
!c : 0
!!c : 1
zero count = 10
non-zero count = 0
설명
- !x : x가 0이면 1, 아니면 0
- !!x: x가 0이면 0, 아니면 1 → 값을 정확히 0/1로 변환할 때 자주 쓴다.
7) Left Shift(<<): 2의 거듭제곱
비트 연산자를 활용한 거듭제곱
코드
#include <stdio.h>
int main()
{
for (int i = 0; i < 10; i++)
printf("2의 %d승 : %d\n", i, 1 << i);
return 0;
}
출력
2의 0승 : 1
2의 1승 : 2
2의 2승 : 4
2의 3승 : 8
2의 4승 : 16
2의 5승 : 32
2의 6승 : 64
2의 7승 : 128
2의 8승 : 256
2의 9승 : 512
설명
- 1 << i는 1을 왼쪽으로 i번 밀어 2^i가 된다.
- 너무 큰 i(예: 31 이상)는 int 범위/부호비트 때문에 위험할 수 있어 범위를 제한하거나 unsigned를 쓰는 게 안전하다.
728x90
반응형
'coding test - C++ > 기본기문제' 카테고리의 다른 글
| [C++] 주요 알고리즘 정리 (BFS, DFS, 다익스트라...) (1) | 2026.02.07 |
|---|---|
| [C++] 코딩테스트를 위한 문법 & 알고리즘 정리 (0) | 2026.02.07 |