#ifdef __cplusplus
extern "C" {
#endif
C++파일이면 extern "C" { 이 구문을 추가하라는 얘깁니다.
이 헤더파일이 C++에서 사용될 경우 C 파일에서 정의된 함수는 C++에서
사용할 수 없기 때문에 미리 정의해놓은 것이지요..
#ifdef __cplusplus
extern "C"
{
#endif
C함수 선언들...
#ifdef __cplusplus
}
#endif
전처리기에서 가장 먼저 수행 되는 부분 입니다. 선행처리기라고도 합니다. 종류로는 #define, #if, #ifdef, #ifndef, #defined, #undef가 있습니다. 이것은 기존에 있는 방대한 소스 코드를 지우지 않고 활성화 비활성화 하는데 가장 많이 이용 합니다. 기존에 있는 소스를 건드리지 않는 상태에서 부분적으로 컴파일 하는곳에 쓰입니다.
#define
구문의 상수로 치환할때 쓰입니다. 대체해서 쓰겠다는 뜻입니다.
또한 #define은 함수 역활 비슷하게 매크로로써 쓰일수 있습니다.
#define SUM(x) ((x) = (x)+(x))
이렇게 쓰일수 있습니다. 동작원리는 함수와 같습니다. 말 그대로 main소스에서 SUM을 호출하면 옆에 있는 더하기 코드가 치환되는 것입니다.
#ifdef, #ifndef
(#ifndef __헤더명_H__)
헤더파일이 겹치는 것을 막기위한 일종의 매크로입니다. 예를들어 헤더파일에다가 어떤 클래스의 인터페이스 선언을 넣었다고 합시다. 이 클래스 인터페이스에서 다른 파일의 프로토타잎이 필요해서 다른 A 파일을 include 하고 있는데 이 헤더 파일을 include 하는 파일에서 A라는 헤더 파일을 이미 include 하고 있다면 두번 define한 것이 됩니다. 그러면 SYNTEX 에러가 나겠지요. 그래서 그런것을 막는 방법의 하나로 #ifndef을 제공합니다. 이전에 include되어 있으면 #endif쪽으로 점프해버려 결국 한번 선언되는 것입니다.
예를 들어
#include
#include
두번 썼다고 합시다. 그런데 앞에 이미 include를 했는데 밑에 또 한다면 문제가 되겠죠. 컴파일러가 검사해야할 코드량도 많아지구요.
그래서 stdio.h 에는
#ifndef _STDIO_H
#define _STDIO_H
가 선언되어 있습니다.
만약 _STDIO_H가 선언되어 있지 않다면 선언한다는 뜻이죠. 그 뒤 (b)에서는 이미 (a) 쪽에서 _STDIO_H 을 선언한 상태이기 때문에 전처리기 쪽에서 무시해버립니다. 그럼 컴파일러는 (a)만 검사하겠죠.
컴파일할 때
#ifdef HAHAHAHA
printf("HAHAHAHA");
#else
printf("HOHOHOHO");
#endif
와 같이 쓰면 만약 HAHAHAHA가 선언되어 있다면 printf("HAHAHAHA");를 전처리기가 컴파일러에게 넘겨주고 아니라면 printf("HOHOHOHO"); 를 넘겨줍니다. 컴파일할 때 전처리기에게 옵션을 줄 수 있습니다. 이것을 보통 preprocessor definition 이라고 하는데요, 전처리기에게 "HAHAHAHA가 있는 부분을 포함시켜!" 라고 옵션을 주는 것이죠. 보통 컴파일러마다 제공합니다. 비주얼 스투디오도 셋팅에 보면 있구요, gcc는 gcc -DHAHAHAHA .......... 와 같이 하면 되죠.
#if
#if 구문은 if랑 아주 비슷합니다.
이것은 어떠한 구문을 컴파일 할지 안할지를 지정할수 있습니다.
#define A 1
#if A
source code.....
#endif
위에는 소스는 컴파일이 됩니다. if문에서와 같이 참, 거짓을 구분하여 컴파일 됩니다. 위에서 A값은 1...즉 0보다 큰수 이기 때문에 참으로 돌아가는 것입니다. 직접 #if 0 .... #endif 이렇게 하면 거짓이기 때문에 이 부분은 컴파일이 되지 않습니다.
#defined
여러개의 define이 되어져 있는지를 검사할때 쓰입니다. 이것은 여러개를 동시에 검사 할수 있습니다.
#if #defined A || #defined B
#undef
위에서 define된 것을 무효화 시키는 것입니다. 예를 들면
#define A 10
이렇게 되있고 뒤에서
#undef A
이렇게 하면 A로 디파인된 값은 무효화 되는 것입니다.
프로그래머들 마다의 코딩 스타일(암시적 약속)이 있습니다. 보통 매크로, const 변수는 대문자로 적는 것이 원칙입니다. 매크로 함수와 일반함수, 매크로대상체(object-like macro)와 일반변수를 구분하기 쉽게 해주는 것이지요.
#define STDIO_H_
왜 뒤에 _를 붙였을까요? 이것도 하나의 암시적 약속입니다. 컴파일러 제작회사는 매크로를 정의할 때 사용자들과 이름이 충돌이 나지 않게 하기 위해서 대부분 _를 뒤어 덧붙입니다. 또한 _를 하나 혹은 두개연속으로 시작하는 것은 컴파일러 내부에서 사용하는 매크로라는 성격이 강합니다. 물론 강제적인 뜻은 없으며 단지 관습상 그렇습니다. 왜 이것이 관습이 되었나하면 보통 매크로 변수이름이나 함수이름을 지을때 뒤에 _를 붙이지 않기 때문입니다. 그래서 함수제작자들이 _를 단골로 붙였습니다.
다음과 같은 매크로는 컴파일러 내부에서 실제로 쓰이며 표준 C에서 인정한 매크로들 입니다. 설마 사용자가 이런 매크로를 정의해서 사용하지는 않겠죠? 물론 다시 정의하면 오류가 나게 됩니다.
__LINE__
__FILE__
__DATE__
__IME__
__STDC__
__STDC
_VERSION__
printf("%d\n", __LINE__); 과 같이 실제로 찍어볼 수도 있습니다.
사실 매크로명은 마음대로 지어도 상관없습니다. 하지만 경력이 많은 C 프로그래머들이 암시적으로 써온 약속들이 있기 때문에 대부분 그렇게 하는 것입니다. 내부적으로 해석되는 것은 토큰이 하나 이상만 되면 모두 매크로 정의가 되는 것이며 하나일 경우 치환은 되지 않습니다.
C의 predefined macro
__FILE__ | a string that holds the path/name of the compiled file |
__LINE__ | an integer that holds the number of the current line number |
__DATE__ | a string that holds the current system date |
__TIME__ | a string that holds the current system time |
__STDC__ | defined as the value '1' if the compiler conforms with the ANSI C standard |
__cplusplus | determines if your compiler is in C or C++ mode. Usually used in headers |
예)
#include <stdio.h>
void main(void)
{
printf("The path/name of this file is %s\n", __FILE__);
printf("The current line is %d\n", __LINE__);
printf("The current system date is %s\n", __DATE__);
printf("The current system time is %s\n", __TIME__);
#ifdef __STDC__
printf("The compiler conforms with the ANSI C standard\n");
#else
printf("The compiler doesn't conform with the ANSI C standard\n");
#endif
#ifdef __cplusplus
printf("The compiler is working with C++\n");
#else
printf("The compiler is working with C\n");
#endif
}
'c or linux' 카테고리의 다른 글
POSIX 쓰레드로 멀티 쓰레드 프로그래밍하기 (0) | 2005.02.18 |
---|---|
함수 포인터 (0) | 2005.02.16 |
ctags 활용 (0) | 2005.02.15 |
Setjmp() (0) | 2005.02.11 |
C언어 함수 (0) | 2005.02.05 |