-프로그램 개발과 유지보수를 쉽게 하고, 가독성을 높이고, 프로그램 포팅(컴퓨터 A에서 만든 것을 B에서 이식 및 실행)을 쉽게 함
-#으로 시작하는 행을 전처리 지시자라고 한다.
#include ...
#define ...
#if ...
-전처리 지시자를 위한 구문은 C언어의 나머지 부분과 독립적이다.
-전처리 지시자가 영향을 미치는 범위는 그 파일에서 전처리 지시자가 있는 위치에서 시작하여 그 파일의 끝까지이거나, 다른 지시자에 의해서 그 지시자의 효혁이 없어질 때까지 이다.
-전처리기는 C를 알지 못한다.
[매크로]
여러가지 종류의 매크로
- 기호상수 (#define N 10)
- 문자열 대치
-인자가 있는 매크로
-정의가 길어질 경우에 현재 행의 끝에 역슬래시 \를 삽입하면 다음 행에 연결해서 계속 쓸 수 있다.
-형태
#define 식별자 상수
- 프로그램의 모든 식별자는 상수로 대치된다.
선언 예제
#define N 60
#define PI 3.14
#define C 299792.458 //km/s
//이미 지정되어있다.
#define EOF (-1)
#define NULl 0
기호 상수
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#define PI 3.14
double circumference(double r) {
return 2.0 * r * PI;
}
double area(double r) {
return r * r * PI;
}
double volume(double r) {
return 4.0 / 3.0 * r * r * r * PI;
}
double surface_area(double r) {
return 4.0 * r * r * PI;
}
int main(void) {
double r;
printf("반지름을 입력하세요: ");
scanf("%lf", &r);
printf("반지름이 %.3f인 \n", r);
printf("원의 원둘레 길이 : %.3f\n", circumference(r));
printf("원의 면적 : %.3f\n", area(r));
printf("구의 부피 : %.3f\n", volume(r));
printf("구의 표면적: %.3f\n", surface_area(r));
return 0;
}
[실행 결과]
문자열 대치
형태
#define 식별자 문자열
프로그램의 모든 식별자는 문자열로 대치된다.
#define EQ ==
#define AND &&
#define OR ||
매개 변수를 갖는 매크로
- 함수와 비슷한 모양을 가진다.
예
#define AREA(x) ((x)*(x)*PI)
//x : 매개변수
//전처리기는 매개변수를 실인자로 대치한다.
기호 상수 예제를 매개변수를 갖는 매크로를 사용해서 수정
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#define PI 3.14
#define CIRCUMFERENCE(x) (2.0 * (x) * PI)
#define AREA(x) ((x)*(x)*PI)
#define VOLUME(x) (4.0/3.0 *(x) *(x) *(x) * PI)
#define SURFACE_AREA(x) (4.0 * (x) *(x)*PI)
int main(void) {
double r;
printf("반지름을 입력하세요: ");
scanf("%lf", &r);
printf("반지름이 %.3f인 \n", r);
printf("원의 원둘레 길이 : %.3f\n", CIRCUMFERENCE(r));
printf("원의 면적: %.3f\n", AREA(r));
printf("구의 부피: %.3f\n", VOLUME(r));
printf("구의 표면적: %.3f\n", SURFACE_AREA(r));
return 0;
}
[출력 결과]
Inline 함수 vs 매개 변수를 갖는 매크로
1. Inline 함수는 컴파일러가, 매크로는 전처리기가 처리한다.
2. 매크로는 인자의 형을 검사하지 않는다.
#define AREA(X) ((x)*(x)*PI)
//AREA(3.1) => 그대로 3.1이 들어간다.
inline int AREA(int n)
{
printf("%d",n);
}
AREA(3.1);
// int형으로 변환되어 3이 출력된다.
3. 매클는 인자들을 여러번 평가한다.
#define AREA(x) ((x) * (x) * PI)
AREA(r++)
=> ((r++) * (r++) * 3.14)
로 계산됨
[유의사항]
매크로를 정의할 때 올바른 평가 순서를 유지하기 위해 괄호를 충분히 사용해야한다.
예시
#define AREA(x) ((x)*(x)*PI)
#define AREA(X) x * x* PI
// 4/ AREA(2)
//AREA(a + b);가 호출 되었을 때, 위 두 문장의 계산결과가 괄호의 유무로 인해 달라진다.
매크로 이름과 매개변수 사이에 공백이 있으면 안된다.
#define AREA(X) ((x)*(x)*PI)
#define AREA (x) ((x)*(x)*PI)
// AREA(5.0)을 호출하게 되면 위의 문장과 다르게
//(x) ((x)*(x)*PI) (5.0)으로 호출이된다.
// AREA(X)가 ((x)*(x)*PI)로 대응되는 것이 아니라
// AREA가 (x) ((x)*(x)*PI)로 대응되는 것이다.
세미콜론 사용에 유의해야한다.
#define AREA(X) ((x)*(x)*PI);
//위 처럼 define문 뒤에 ;가 붙었을 때,
// if(r>0) x = AREA(r); else x = -1;이 실행 되었을 때
//if(r>0) x = ((r)*(r)*PI);;처럼 ;이 중복되어서 실행된다.
[#연산자 : 문자열화 연산자]
형식
#define string(a) #a
string(주라기 공원)
//"주라기 공원"으로 문자열 상수화
쓰임 : 디버깅 코드에 주로 쓰인다.
#define PRINT_VAR(x) printf(#x"=%d\n",x)
printf("i = %d\n", i);
PRINT_VAR(i);
printf("j = %d\n", j);
PRINT_VAR(j);
//printf("j = %d\n", j)을 일일이 쓰기 힘들다면 문자열화 매크로를 사용
인자 생략
#define print_age(x) printf(#x"x : %d", r);
//c99부터는 인자 생략을 허용
print_age();
//위 호출문은 아래와 같이 바뀐다.
printf(" " ": %d\n ", r);
헤더 파일
- .h 파일
ex) 1.h, stdio.h , stdlib.h
-#include , 매크로 정의, 함수 원형(선언), 기호 상수 등이 해당 헤더 파일 안에 정의 되어 있음
-시스템이 제공하는 헤더 파일(표준 헤더 파일)
-stdio.h, stdlib.h , string.h 등
-사용자도 자신의 헤더 파일을 만들 수 있다.
: 사용자 헤더 파일은 소스 파일과 같은 디렉터리에 생성한다.
-#include를 통해 프로그램에 삽입한다.
#include
- 뒤에 명시된 파일을 #include 문장 대신에 삽입한다.
-어떤 종류의 파일도 명시해도 되지만, 보통 헤더 파일(*.h)을 명시한다.
-파일을 명시하는 두 가지 방법
#include <filename>
- 표준 헤더 파일을 삽입할 때 사용한다.
- 시스템이 정의한 디렉토리에서 filename 파일을 찾아 삽입한다.
- 일반적으로 , 표준 헤더 파일이 저장된 장소는 시스템에 따라 다르다.
# include "filename"
- 사용자 헤더 파일을 삽입할 대 사용한다.
- 먼저 현재 디렉토리에서 검색하고, 거기에 없다면 시스템이 정의한 디렉토리에서 검색하여 삽입한다.
//위 헤더 define이 중복된다면, 한꺼번에 pi.h 만들기
#include <stdio.h>
#define PI 3.14
#define CIRCUMFERENCE(x) (2.0 * (x) * PI)
#define AREA(x) ((x)*(x)*PI)
#define VOLUME(x) (4.0/3.0 *(x) *(x) *(x) * PI)
#define SURFACE_AREA(x) (4.0 * (x) *(x)*PI)
//만들어둔 pi.h를 포함
#include "pi.h"
int main(void) {
double r;
printf("반지름을 입력하세요: ");
scanf("%lf", &r);
printf("반지름이 %.3f인 \n", r);
printf("원의 원둘레 길이 : %.3f\n", CIRCUMFERENCE(r));
printf("원의 면적: %.3f\n", AREA(r));
printf("구의 부피: %.3f\n", VOLUME(r));
printf("구의 표면적: %.3f\n", SURFACE_AREA(r));
return 0;
}
'c언어' 카테고리의 다른 글
[C언어] 사용자 정의형 - 구조체 (0) | 2022.10.24 |
---|---|
[C언어] 비트 수준 접근 (0) | 2022.10.23 |
[C언어] 공용체(union) / 열거형 (0) | 2022.10.12 |
[C언어] 동적 메모리 할당 (0) | 2022.09.07 |
[C언어] 포인터와 배열 (0) | 2022.09.07 |