C 과제: 매크로의 활용 #1

2 분 소요

질문

내용

int 배열의 원소를 출력하는 함수 매크로를 문자 배열이나 실수 배열의 원소도 출력할 수 있도록 수정하시오.

실행 결과

실수 배열의 초기값? 0.1
[x] 0.1 0.1 0.1 0.1 0.1
문자 배열의 초기값? @
[y] @ @ @ @ @

답변

내용

필자는 문제의 내용 중 자료형과 관계없이 배열의 원소를 출력하라는 조건을 통해 모든 자료형들을 문자열로 통일하여 사용자로부터 이를 입력받아 매크로로 처리하면 되겠다고 생각하였다.

그래서 일단 길이가 10인 문자 배열 하나를 main 함수 내에 선언하였으며,

int main(void) {
    char input[10];

    return 0;
}

다음과 같이 문제에 주어진 실행결과와 동일한 출력 결과를 얻기 위해 적절한 출력문과 입력문도 함께 구성해주었다. (물론 printf()와 scanf() 함수를 사용하기 위해서는 이와 관련된 헤더파일(stdio.h) 선언도 잊지 말자.)

#include <stdio.h>

int main(void) {
    char input[10];

    printf("실수 배열의 초기값? ");
    scanf("%s", input);

    return 0;
}

이렇듯 input이라는 길이가 10인 1차원 배열에 사용자로부터 문자열을 입력받았다면,

입력받은 문자열들에 대해 총 5회 반복을 진행하는 함수 매크로만 작성해주면 된다.

함수 매크로는 다음과 같으며,

#define PRINT_INPUT(X) for(int i=0; i<5; i++) printf("%s ", (X)) 

아래와 같은 구문이 있을 시

PRINT_INPUT(input);

이는 전처리기에 의해 다음 구문들로 변경된다.

for(int i=0; i<5; i++) printf("%s ", input);

왜 필자가 매크로를 아래와 같이 작성하였는지 이해하였는가?

#define PRINT_INPUT(X) for(int i=0; i<5; i++) printf("%s ", (X))

이를 본 코드에 결합시키고 실행 결과와 동일한 결과가 출력되게끔 적절한 출력문까지 작성해주면 다음과 같다.

#include <stdio.h>

#define PRINT_INPUT(X) for(int i=0; i<5; i++) printf("%s ", (X))      // 총 5회의 출력을 위한 매크로

int main(void) {
    char input[10];

    printf("실수 배열의 초기값? ");
    scanf("%s", input);

    printf("[x] ");
    PRINT_INPUT(input);

    return 0;
}

여기까지 작성하였다면, 문자 배열에 대해서도 동일한 방식으로 코드를 작성해주면 되겠다.

아래에 전체 코드를 보였으니 이를 확인해보자.

전체 코드

#include <stdio.h>

#define PRINT_INPUT(X) for(int i=0; i<5; i++) printf("%s ", (X))

int main(void) {
    char input[10];

    printf("실수 배열의 초기값? ");
    scanf("%s", input);

    printf("[x] ");
    PRINT_INPUT(input);

    printf("\n문자 배열의 초기값? ");
    scanf("%s", input);

    printf("[y] ");
    PRINT_INPUT(input);

    return 0;
}

한계

전체 코드를 보이기만 하고 이 포스팅을 마무리 짓는다면 별 의미 없는 포스팅이 될 듯 하여 필자가 독자 여러분께 질문 하나를 던지겠다.

위 코드의 한계는 무엇일까?

만약 길이가 10인 문자열이 사용자로부터 입력되어진다면, 어떠한 일이 발생하는가?

이는 오버플로우(overflow)의 발생으로 이어질 것이다. (널 문자(Null Character)까지 고려해보았을 때 총 길이가 11이므로)

이러한 한계를 극복하기 위해 필자는 여러분께 위 코드를 동적 메모리 할당(Dynamic Memory Allocation)이라는 개념을 이용하여 재작성해볼 것을 추천하는 바이다.

또한 매크로 함수 사용 관점에서 보면, 만약 지금과 같은 단순한 문제 상황이 아닌 조금만 복잡해지는 문제 상황이 주어진다면, 원하는 결과를 얻기 위한 매크로 함수의 구현이 더더욱 어려워진다는 점이다.

원하는 결과를 얻기 위해 보통 소괄호를 여러 번에 걸쳐 사용하는데, 이렇듯 과도한 소괄호 사용으로 인해 버그(Bug)를 찾고 수정하는 일(디버그(Debug))도 쉽지 않을 뿐만 아니라, 코드의 가독성도 떨어지게 된다.

그러므로 특수 상황을 제외한 함수 매크로의 사용은 최대한 지양하는 것이 좋다.

댓글남기기