끝나지 않는 프로그래밍 일기


1. #include


#include(포함하다,~을 포함시키다)란 녀석은 외부에 선언되어 있는 함수 혹은 상수 등을 사용하기 위하여(구현과 선언의 분리) 선언해야 하는 것으로 이것은 #define와 같이 전처리기라 불리며 컴파일 이전에 미리 처리되는 문장(선행처리)을 말합니다. 우리가 printf, scanf 함수를 사용하기 위해 사용했던 #include <stdio.h>의 역할은 stdio.h의 내용이 소스에 포함되게 합니다. #include를 쓰는 대신 헤더 파일의 내용을 복사해도 똑같은 결과를 출력합니다. #include를 사용하면 그 헤더파일의 선언된 함수를 쓸수 있게되며, 파일의 이름을 적는데 사용되는 괄호는 두가지의 경우로 나뉩니다.

C에서 제공하는 표준 헤더파일을 포함 시킬때는 <>를 사용합니다. 예를 들어 stdio.h, stdlib.h, string.h 등이 포함됩니다. (C++에서는 C와 구분하기 위해 .h를 없애고 앞에 c를 붙임. math.h는 cmath) 그리고 사용자가 직접 작성한 헤더를 포함시킬때는 ""를 사용합니다. ""를 사용하면 이 방식은 같은 폴더 내에있는 헤더 파일을 먼저 찾으며, 만약 찾지 못한 경우 다른 폴더도 탐색합니다. 또한, 헤더 파일의 이름뿐만 아니라 절대경로도 지정할수 있습니다. 


예:

#include "C:\Study\header1.h"
#include "C:\Study\header2.h"


2. #define


#define은 함수 혹은 상수를 단순화 하거나, 어느 특정한 상수에 이름을 붙여줌으로써 가독성을 증가시키는 등 여러가지 장점을 지니고 있습니다. 아래는 매크로 상수를 정의할때 사용되며 구성은 다음과 같습니다.

#define 상수명 상수

구성을 보면 알수 있듯이 define 뒤에 등장하는 것은 상수명이며, 그 뒤에 등장하는 것은 상수 입니다. 만약에 상수명이 PI라고 가정하고 그 값이 3.14라고 가정합니다. 그러면 아래와 같이 만들수 있습니다.

#define PI 3.14

선행처리기는 이 명령문을 받아 매크로 PI를 3.14로 전부 치환하며 전처리문은 뒤에 세미콜론이 오지 않습니다.

#include <stdio.h>

#define PI 3.141592

int main()
{
	double dim;

	scanf("%lf", &dim);
	printf("%0.lf * %0.lf * %lf = %lf\n", dim, dim, PI, dim * dim * PI);
}

결과:

4
4 * 4 * 3.141592 = 50.265472
계속하려면 아무 키나 누르십시오 . . .


코드와 결과를 잘 살펴보시면, PI가 3.141592로 대체됨을 알 수 있습니다. 즉 dim의 값으로 4가 입력되었다고 가정하면, 4 * 4 * 3.141592 라는 식이 나오는 것입니다. 이 define란 녀석은 '단순 치환'이며, 전처리 과정에서 PI는 define로 인해 상수로 치환되어 버립니다. 물론, 상수뿐만이 아니라 위에서 말했듯이 함수도 define 전처리기를 통하여 정의할 수 있습니다. 아래와 같이 말입니다.


예>

#include <stdio.h>
#define SUM(X, Y) ((X)+(Y))

int main()
{
 int a = 10, b = 20;

 printf("%d\n", SUM(a, b));
}

결과:

30
계속하려면 아무 키나 누르십시오 . . .


위에서는 SUM(a, b)가 ((a)+(b))로 대체됨을 아실 수 있습니다. 즉, a의 값은 10 그리고 b의 값은 20이니 SUM(a, b)는 ((10)+(20))으로 치환이 된 셈입니다. 여기서 주의하실 점은, SUM(a, b)는 함수처럼 반환이 되는게 아니라, 전처리 과정에서 모두 치환이 되어버리는 것입니다. 더 확실한 이해를 위해 예제를 살짝 변형하여 다시 살펴보도록 합시다.


예>

#include <stdio.h>
#define SUM(X, Y) X+Y

int main()
{
 int a = 10, b = 20;

 printf("%d\n", SUM(a, b) * 100);
}

결과:

2010
계속하려면 아무 키나 누르십시오 . . .


2행의 괄호를 제거하고, 8행에서 SUM(a, b) 뒤에 100을 곱하는 연산을 수행하도록 했습니다. 그런데, 10과 20을 더해 30이란 값에 100을 곱한 결과값인 3000이 아닌, 엉뚱하게도 2010이란 결과값을 내뱉었습니다. 그 이유는 뭘까요? 바로 SUM(a, b)가 전처리 과정에서 a + b로 치환되고 a + b * 100이란 식이 만들어지기 때문입니다. 그렇다면 연산자 우선순위로 인해 덧셈(+)부터가 아닌 곱셈(*)부터 수행되어 20에다 100을 곱하고 마지막으로 10을 더해 2010이란 결과가 나오는 것입니다. 이 때문에, 상수 혹은 함수를 define으로 정의할 경우에는 괄호를 잘 감싸주어야 한다는 것입니다.