주석
- 프로그램 중 실행하지 말라고 표시한 부분
- 주석으로 표시되면 컴파일하기 전에 제거
- 프로그램에 설명을 추가하거나 프로그램의 일부분을 잠시 실행하고 싶지 않을 때 사용
// 한 문장을 주석 처리
/* 여러 문장을
주석 처리 할 때
사용 */
매크로
- 프로그램의 수정이 용이
- 상수들에 이름을 부여함으로써 프로그램의 이해를 도움
- 매크로 속에 또 다른 매크로를 넣을 수 있음
- 수식은 괄호로 감싸는 것이 좋음
매크로 함수
- Macro with arguments
- 함수와 같은 형태를 가진 매크로들
- 인자 자리에 있는 것들이 해당 매개변수 위치로 치환
#define MAX(x,y) ((x)>(y) ? (x) : (y))
e = MAX(a+b,c+d);
- 일반 함수는 값이 대입이 일어나므로 자료형을 맞춰야하지만 매크로 함수는 텍스트의 치환이므로 자료형과는 무관
매크로 함수 주의점
- 치환할 텍스트 안에 있는 모든 매개변수 주위와 치환 텍스트 전체를 괄호로 감싸야 함
#define MULT(x,y) x*y
e = MULT(2+1,3+2);
// 결과: e = 2+1*3+2 = 7
#define MULT(x,y) ((x)*(y))
e = MULT(2+1,3+2);
// 결과: e = ((2+1)*(3+2)) = 15
- 겉보기와 다르게 동작할 수 있음
#define MAX(x,y) ((x)>(y) ? (x) : (y))
e = MAX(a++,b);
// 매크로 함수의 수식에서 크기 비교를 위한 (x)>(y) 부분에서 a++로 한번 증가
// 그 뒤 (x) : (y) 부분도 a++로 치환되기 때문에 a가 한번 더 증가함
- 문자열 안은 매크로 치환 불가
매크로 함수가 필요한 경우
- 매크로 함수의 치환 텍스트에서 매개변수 앞에 #이 있으면, 해당 인자를 문자열로 변환하여 치환
...
printf("a = %f\n", a);
printf("b = %f\n", b);
printf("c = %f\n", c);
printf("d = %f\n", d);
printf("e = %f\n", e);
...
#define PRINT(expr) printf(#expr " = %f\n", expr)
// PRINT(a);를 하게 되면 #expr은 a가 아니라 "a"로 치환됨
// 따라서 PRINT(a);는 printf("a" " = %f\n", a);가 됨
// 연속된 문자열은 연결된 것으로 취급, printf("a = %f\n", a);
...
PRINT(a);
PRINT(b);
PRINT(c);
PRINT(d);
PRINT(e);
...
- ##: 치환 텍스트에 사용될 경우, 인자와 다른 글자들을 붙여줌
#define VNAME(n) a##n
VNAME(3) = 10;
// a3 = 10; 이 됨
전처리 과정
#include
- 해당 파일을 가져와서 포함시킴
- #include <파일이름>: 해당 파일을 시스템에서 제공하는 헤더 파일들에서 찾음
- #include "파일이름": 해당 파일을 사용자가 작성한 파일들에서 찾음
조건부 컴파일
- 컴파일 과정에서 어느 부분을 포함시킬지 결정
- 조건부 컴파일을 사용하는 이유
- 같은 프로그램을 조금씩 기능을 다르게 하며 컴파일 할 때
- 소프트웨어를 판매할 때, 간단한 기능만 되는 것과 모든 기능이 되는 것으로 두 가지 버전을 판매할 때
- #if, #endif, #elif, #else
- #if 다음의 조건식이 맞으면 #if와 #endif 사이의 문장들을 컴파일함
- 조건식이 틀리면 #if와 #endif 사이의 문장들을 컴파일하지 않음
- #if의 조건식은 컴파일하기 전에 판단하기 때문에 조건식이 상수식이며 컴파일하기 전에 판단 가능해야함
- #if도 중첩이 가능하고 관계 연산자나 논리 연산자 사용 가능
- defined
- defined(매크로) 또는 defined 매크로로 사용
- 해당 매크로가 정의되어 있으면 1, 그렇지 않으면 0
- 매크로가 무엇으로 정의되어 있는지는 상관없음
- 줄여서 #ifdef로 사용가능, #ifndef는 #if !defined와 동일
#define LEVEL
...
#if defined(LEVEL)
...
...
#endif
열거형
- 정수의 특정한 이름 부여
- 각 정수의 이름들을 기호 상수라고 부름
- 특정하게 약속한 정수값의 의미를 명확하게 드러내고 싶을 때 사용
enum days {Sun, Mon, Tue, Wed, Thu, Fri, Sat};
enum days a, b;
a = Tue;
b = a+3;
if(b == Fri) printf("It's Friday!");
유도 자료형
- 기본 자료형: int, char와 같이 문법적으로 주어지는 자료형
- 유도 자료형: 구조체와 같이 다른 자료형을 이용해서 만드는 자료형
- 구조체, 공용체, 비트필드
공용체
- Union
- 구조체와 거의 유사하지만 멤버들이 같은 메모리 공간을 공유함
- 공간을 공유하므로 다른 멤버에 값을 저장하면 기존 멤버의 값은 사라짐
union val {
int i;
double f;
};
union val a;
a.i = 3;
a.f = 2.0;
// a.f 값 저장 시 a.i의 값이 사라짐
비트 필드
- 구조체와 거의 유사
- 멤버들이 비트 단위의 크기를 가지는 정수형
- 멤버들의 자료형은 unsigned 혹은 signed int형만 가능
- 일반적인 구조체처럼 사용
struct bits {
unsigned int a: 3;
signed int b: 5;
unsigned int : 2;
unsigned int : 0;
unsigned int c: 4;
};