C 언어는 오랜 역사만큼이나 의외의 동작과 잘 알려지지 않은 문법적 특징들을 많이 가지고 있습니다. 이번 글에서는 일상적인 코딩에서는 잘 접하지 못하지만, 표준 C 규격 안에서 실제로 동작하는 재미있는 사실들을 코드 예제와 함께 살펴보겠습니다.
1. switch 문의 case 라벨이 if-else 문 안에 들어갈 수 있다
case 라벨은 단순히 점프 지점을 표시하는 라벨일 뿐이기 때문에, switch 블록 내부라면 if-else 문 안에 위치할 수도 있습니다. 컴파일러는 case 키워드 자체를 일반 라벨처럼 처리합니다.
예제
#include <stdio.h>
main() {
int x = 2, y = 2;
switch(x) {
case 1:
;
if (y==5) {
case 2:
printf("Hello World");
}
else case 3: {
//case 3 block
}
}
}
출력 결과
Hello World
x의 값이 2이므로 실행 흐름은 if 문 안쪽에 있는 case 2로 점프하여 "Hello World"가 출력됩니다. 물론 이런 코드는 가독성을 해치므로 실무에서는 권장되지 않지만, C의 유연함을 보여주는 좋은 예입니다.
2. array[index]를 index[array]로 쓸 수 있다
배열 요소는 포인터 연산(pointer arithmetic)으로 접근됩니다. 즉, array[5]는 컴파일러에 의해 *(array + 5)로 해석됩니다. 덧셈은 교환 법칙이 성립하므로, 이를 뒤집어 쓴 5[array] 역시 *(5 + array)와 같은 의미가 되어 정상적으로 동작합니다.
예제
#include <stdio.h>
main() {
int array[10] = {11, 22, 33, 44, 55, 66, 77, 88, 99, 110};
printf("array[5]: %d\n", array[5]);
printf("5[array]: %d\n", 5[array]);
}
출력 결과
array[5]: 66 5[array]: 66
3. <: :> 와 <% %> 로 대괄호와 중괄호를 대체할 수 있다
C 표준에는 다이그래프(digraph)라고 불리는 대체 토큰이 정의되어 있습니다. 키보드 환경 등의 이유로 특수 문자를 입력하기 어려운 경우를 위해 마련된 것으로, <: 와 :> 는 대괄호 [ ] 를, <% 와 %> 는 중괄호 { } 를 대신할 수 있습니다.
예제
#include <stdio.h>
main() <%
int array<:10:> = <%11, 22, 33, 44, 55, 66, 77, 88, 99, 110%>;
printf("array[5]: %d\n", array<:5:>);
%>
출력 결과
array[5]: 66
4. #include를 예상치 못한 곳에서 사용할 수 있다
#include는 전처리기가 해당 위치에 파일의 내용을 그대로 붙여 넣는 동작을 하기 때문에, 헤더 선언부가 아닌 곳에서도 사용할 수 있습니다. 예를 들어 abc.txt 파일에 다음 한 줄이 저장되어 있다고 가정해 보겠습니다.
"The Quick Brown Fox Jumps Over The Lazy Dog"
printf 함수 호출문 뒤에 이 파일을 포함시키면, 전처리 과정에서 파일 내용이 printf의 인자로 합쳐져 그대로 출력됩니다.
예제
#include <stdio.h>
main() {
printf
#include "abc.txt" ;
}
출력 결과
The Quick Brown Fox Jumps Over The Lazy Dog
5. scanf()에서 %*d로 입력을 건너뛸 수 있다
scanf 형식 문자열에서 별표(*)는 할당 억제(assignment suppression)를 의미합니다. %*d를 사용하면 해당 위치의 정수 입력을 읽기만 하고 변수에 저장하지 않고 무시할 수 있습니다.
예제
#include <stdio.h>
main() {
int x;
printf("Enter two numbers: ");
scanf("%*d%d", &x);
printf("The first one is not taken, the x is: %d", x);
}
출력 결과
Enter two numbers: 56 69 The first one is not taken, the x is: 69
두 개의 숫자를 입력했지만 첫 번째 값(56)은 %*d에 의해 버려지고, 두 번째 값(69)만 변수 x에 저장된 것을 확인할 수 있습니다.
이처럼 C 언어는 겉으로 보기에는 단순해 보이지만, 표준 규격 깊숙이 들여다보면 의외의 동작들이 많이 숨어 있습니다. 이런 특성들은 코딩 테스트나 동료들의 코드 리뷰에서 종종 마주칠 수 있으니, 원리를 이해해 두면 큰 도움이 됩니다.