Computer >> 컴퓨터 >  >> 프로그래밍 >> C 프로그래밍

C 프로그래밍의 숨겨진 흥미로운 사실들

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 언어는 겉으로 보기에는 단순해 보이지만, 표준 규격 깊숙이 들여다보면 의외의 동작들이 많이 숨어 있습니다. 이런 특성들은 코딩 테스트나 동료들의 코드 리뷰에서 종종 마주칠 수 있으니, 원리를 이해해 두면 큰 도움이 됩니다.