본문 바로가기

C언어

심화 C 언어 7 (매크로 - C/C++의 독특한 매력)

전처리기 # 

전처리는 모두 #으로 시작한다

#include 또한 #으로 시작하기 때문에 전처리 즉 매크로

#define_CRT_SECURE_NO_WARNINGS 구문도 마찬가지

#으로 시작했기 때문에 전처리 이다

 

#include

#include 전처리기는 소스코드의 텍스트를 그대로 복사해서 붙여넣는 전처리기다

이를 통해 C/C++ 는 함수의 선언이 존재함을 이해할 수 있고

이를 통해 우리가 만들어두지 않은 함수들인 printf 나 scanf 등을 활용할 수 있다

 

#define

#define 전처리는 적당한 규칙으로 소스코드를 교체할 수 있으며,

이를 통해 프로그래머가 상수를 지정할 수 있고,

매크로 함수 또한 지정할 수 있다

 

정확히 알아둬야 할 것은 #define으로 만들어진 매크로 함수는 실제로 함수의 역할을 하는 것이 아닌 함수처럼,

소스코드를 직접 변경시켜준다는 뜻, 전처리는 소스코드를 컴파일 직전에 그냥 교체해 주는 역할

이를 이용해 상수와 매크로 함수를 사용할 수 있다

 

매크로 함수

#define 매크로 (전처리) 함수를 호출하면

어떤 실행이 컴퓨터 연산에 의해 일어나는 것이 아닌

그냥 아예 소스코드가 바뀌어버리게 된다

이 매크로 함수는 실제로 컴퓨터에서 동작하는 함수가 아닌 소스코드를 그냥 교체해버리는 함수다

 

#define _CRT_SECURE_NO_WARNINGS


#define SWAP(X, Y, T) T = X; X = Y; Y = T;
// 전처리 함수는 앞쪽에는 파라미터를 받는 것은 똑같은데 이 파라미터를 이용해서 이런 규칙에 맞게 소스코드를 교체 해 주기만 하면 됨
// 두 줄로 만들고 싶을때 \ 을 써주면 된다, \ 뒤에 공백(스페이스) 있으면 안됨
#define SWAP(X, Y, T)\
 T = X; X = Y; Y = T; 이런식으로!
 
#include <cstdio>

int main() {
    int v1 = 100;
    int v2 = 200;
    int temp;
    
    SWAP(v1, v2, temp);
    // temp = v1; v1 = v2; v2 = temp; 이 코드와 동일
    // 전처리 함수는 이 전처리 함수에 맞는 규칙에 의해서 소스코드를 교체
    // 규칙에 맞춰서 바뀐다 > v1이라는 토큰은 X로 인식하고 v2라는 토큰을 Y로 인식하고 temp라는 토큰을 T로 인식했을 때
        T는 X라고 그냥 바꿔버림, 장점은 속도가 빠르다 단점은 실행 파일의 크기가 커진다
    
    printf("v1 : %d\n", v1);
    printf("v2 : %d\n", v2);
   
    return 0;
}

매크로의 특징으로 이거는 알고 넘어가야할 특징

소스코드를 직접적으로 물리적으로 교체하고 바꾸는 것이기 때문에 P(X, Y) X##Y 요런 것도 가능

#define _CRT_SECURE_NO_WARNINGS

#define P(X, Y) X##Y

#include <cstdio>

int main() {
    int v1 = 100;
    int v2 = 200;
    int temp;
    
    P(print, f("Hello World"));
   
    return 0;
}

 

매크로 상수

#define 매크로(전처리) 를 사용하면 상수 (Constants)를 지정할 수도 있다

 

상수프로그램의 시작부터 종료까지 절대 변하지 않는 값을 상수라고 한다

 

매크로는 #define을 통해 값을 아예 지정해 버릴 수 있다

교체되는 특성을 이용해서 

#define PI 3.141592 이런식으로 지정해줄 수 있다

#include <cstdio>


#define PI 3.141592


int main() {
    float pi = PI;
    // 매크로 상수가 실행시 교체되서 여기가 컴파일 될 떄 pi = 3.141592 이런식으로 교체되서 들어감
   
    return 0;
}

 

조건 - #if #elif #else #endif

#define 매크로와 연계하여 매크로 (전처리) 조건을 넣을 수 있다

 

#if <매크로 조건> // if ( ... ) {} 구문과 비슷

실행하고 싶은 구문

#elif <매크로 조건> // else if ( ... ){} 구문과 비슷

실행하고 싶은 구문

#else // else {} 구문과 비슷

실행하고 싶은 구문

#endif 

#include <cstdio>

#define PI 3.141592

#define EXECUTE_NUM 0


#if EXECUTE_NUM == 0
int main() {
    printf("Hello World\n");
    return 0;
}
#else
int main() {
    printf("Hello World 1\n");
    return 0;
}
#endif


// 매크로에 의해서 실행되는 #if를 이용해서 구문을 지정해줄 수 있다
// 여러개의 main 함수를 만들어 놓고 내가 원하는 것만 실행할 수 있게 한다든지,
그런 플랫폼에 따라서 어떤 코드가 실행이 될 수 있을지를 결정을 해준다든지 여러가지 것들을 해줄 수가 있다

// 전처리 매크로는 아예 소스코드 자체를 교체해버린다는 장점이 있다, 소스코드 자체가 교체돼버리기 떄문에
즉, 지금 EXECUTE_NUM가 1일 떄는 아예 이 소스코드 자체가 없는 것 처럼 취급, 함수 호출이 다른 부분을 아예 감춰 버릴 수가 있다,
또한 매크로기 때문에 실행 속도가 좋다

조건  #ifdef #else #endif

 

#define 매크로 와 연계하여 매크로 (전처리) 조건을 넣을 수 있다

 

#ifdef 매크로 이름 // 해당 이름의 매크로가 정의되어 있다면

실행하고 싶은 구문

#else // else {} 구문과 비슷

실행하고 싶은 구문

#endif 

#include <cstdio>


#define PI 3.141592


#define EXECUTE_NUM 0


#ifdef EXECUTE_NUM

// #ifdef라는 것은 define이 되어있냐 되어있지 않느냐를 기준으로 판단
// define 이 되어있으면 아래 코드 실행, 아닐 시에는 #else 코드를 실행

int main() {
    printf("Hello World 0\n");
    return 0;
}
#else
int main() {
    printf("Hello World 1\n");
    return 0;
}
#endif

조건  #ifndef #else #endif

 

#define 매크로 와 연계하여 매크로 (전처리) 조건을 넣을 수 있다

 

#ifndef 매크로 이름 // 해당 이름의 매크로가 정의되어 있지 않다면

실행하고 싶은 구문

#else // else {} 구문과 비슷

실행하고 싶은 구문

#endif 

 

연습 프로그래밍

두 변수의 값을 바꾸는 SWAP(X, Y, TYPE) 매크로 함수를 

변수 두 개와 변수의 타입을 매크로 인자로 받아서 만들어 보세요

(temp 라는 임시 변수를 사용하지 않기)

#include <cstdio>


#define SWAP(X, Y, TYPE) TYPE temp = v1; v1 = v2; v2 = temp;


int main() {
    int v1 = 100;
    int v2 = 200;
    
    SWAP(v1,v2, int);

    // SWAP(v1,v2, int);
    // SWAP을 두 번 실행시 오류, braket 으로 이루어진 함수가 아니여서 오류가 뜸
    // #define SWAP(X, Y, TYPE) {TYPE temp = v1; v1 = v2; v2 = temp;} 해주면 괜찮음
    // 아니면 {SWAP(v1,v2, int);} 이렇게 두 번 실행해주면 됨
    
    // SWAP(v1,v2, int);은
     int temp = v1;
     v1 = v2;
     v2 = temp; 이렇게 변환이 되는 것
    
    
    printf("v1 = %d\n", v1);
    printf("v2 = %d\n", v2);
    
    return 0;
}

미션 문제

다섯개의 수의 평균을 구하는 매크로 함수를 만들어 주세요

#include <cstdio>


#define AVG(A, B, C, D, E, R ) R = (A + B + C + D + E)/5


int Input();
int Input(){
    int input;
    printf("숫자를 하나씩 입력하세요 : ");
    fseek(stdin, 0, SEEK_END);
    scanf("%d", &input);
    return input;
}


int main() {
    int a,b,c,d,e, result;
    a = Input();
    b = Input();
    c = Input();
    d = Input();
    e = Input();
    
    AVG(a, b, c, d, e, result);
    
    printf("평균은 %d 입니다.\n", result);
    
    return 0;
}