IT공부/윤성우 열혈 C프로그래밍

C언어의 깊은 이해_4

doublehyun 2022. 3. 6. 21:40

Chapter.6 매크로와 선행처리기

  • 선행처리기와 매크로
    • 선행처리기 : 컴파일 이전의 처리
         
    • 선행처리 명령대로 소스코드의 일부를 단순 치환한다 이때 #을 붙이고, 세미콜론은 붙이지 않는다
  • 대표적인 선행처리 명령문
    • #define PI 3.141592
      • #define(지시자), PI(매크로), 3.141592(매크로 몸체) 라 표현한다
      • 뜻은 매크로PI를 매크로몸체 3.14~로 치환해라 라는 뜻
    • #define SQUARE(X) X*X
      • 함수와 유사한 메크로(functuon-like macro) 즉 매크로 함수 이다
      • SQUARE(X) 등장시 X*X로 치환하라는 뜻이다 ex) SQUARE(123) -> 123*123
    • 잘못된 매크로 정의
      • ex) SQUARE(3+2) 의 경우 3+2*3+2 = 11이 출력된다(25가 아니라)
      • 이때 3+2에 괄호를 쳐주면 (3+2)*(3+2) = 25로 정상적인 값이 나오게 된다
      • 따라서 매크로 몸체에 괄호를 쳐준다 SQUARE(X) ( (X)*(X) ) // 매개변수에 괄호, 전체 함수에 괄호
    • 두줄에 걸쳐 매크로 정의하기
      • define SQUARE(X) \
      • ((X)*(X))
    • 매크로 정의 시, 먼저 정의된 매크로도 사용 가능!
    • 매크로 함수의 장점
      1. 일반 함수에 비해 실행속도가 빠르다
      2. 자료형에 따라 별도로 함수를 정의하지 않아도 된다
    • 매크로 함수의 단점
      1. 정의하기가 정말로 까다롭다
      2. 디버깅 하기가 쉽지 않다
    • 따라서 매크로 할 함수의 특징
      1. 작은 크기의 함수
      2. 호출의 빈도수가 높은 함수
  • 조건부 컴파일을 위한 매크로
    • #if... ~ #endif = 참이라면
      • #if 뒤에 오는 인자가 참이면 #endif 전까지 있는 코드 컴파일, 참이 아니면 #endif 전까지 있는 코드 생략!
    • #ifdef... ~ #endif = 정의 되었다면
      • #ifdef 뒤에 오는 매크로가 정의되어 있으면 #endif 전까지 있는 코드 컴파일, 정의되지 않으면 #endif 전까지 있는 코드 생략!
    • #ifndef... ~ #endif = 정의 되었다면
      • #ifndef 뒤에 오는 매크로가 정의되지 않으면 #endif 전까지 있는 코드 컴파일, 정의되어 있으면 #endif 전까지 있는 코드 생략!
    • #else의 삽입 
      • #if, #ifdef, #ifndef 에 사용 가능하다
      • if문과 동일하게 사용된다
    • #elif의 삽입
      • #if 문에만 사용 가능하고 여러번 사용 가능하다
      • if문의 elseif와 동일하게 사용된다
  • 매개변수의 결합과 문자열화
    • 문자열 내에서는 매크로의 매개변수 치환이 발생하지 않는다
      • ex) define ST_job(A, B) "A의 직업은 B입니다" 선언후 ST_job(이중현, 학생) 실행시  A의 직업은 B입니다 가 치환된다
    • 따라서 문자열 내에서 매크로를 치환하려면 # 연산자를 사용면 된다
      • ex) define ST_job(A, B) #A "의 직업은" #B "입니다" 는 이중현의 직업은 학생입니다 로 치환된다
    • 필요한 형태대로 단순하게 결합하기 : 매크로 ##연산자
      • ex) define STNUM(Y, S, P) Y ## S ## P 선언후 STNUM(18, 11, 21) 은 181121 로 치환된다

Chapter.7 파일의 분할과 헤더파일의 디자인

  • 파일의 분할
    • 컴파일러는 파일 단위로 컴파일을 진행한다, 따라서 다른 파일의 정보를 참조하여 컴파일을 진행하지 않는다
    • 외부에 선언 및 정의되어 있다면 컴파일러에게 미리 알려줘야 한다!!
      • extern int num; -> 외부에 int num 이라는 변수가 선언되어 있다 라고 알려준다
    • 다른 파일에서 접근을 못하게 막고 싶다면 static을 선언하면 된다 (static int num;) -> 접근 범위를 파일 내부로 제한한다
  • 헤더파일의 디자인과 활용
    • #include 지시자의 의미 = 이 문장의 위치에 해당 파일에 저장된 내용을 가져다 놓으세요
    • 헤더파일을 include 하는 두가지 방법
      1. #include <헤더파일 이름> = C의 표준에서 정의하는, 기본적으로 제공되는 헤더파일을 포함시킬때 사용
      2. #include "헤더파일 이름" = 프로그래머가 정의한 헤더파일을 포함시킬때 사용
    • 헤더파일에 담겨야 하는 내용
      • extern 이 선언되어야 하는 함수, 변수를 미리 선언해 놓는다
      • 구조체를 저장해 사용할 경우 헤더파일에 저장해서 모두 사용할 수 있게 한다
      • 헤더파일의 중복 삽입 문제
      • 다음과 같은 경우 구조체 div가 두번 삽입된 형태가 되어 컴파일 에러가 발생한다
        • 헤더파일의 중복 삽입이 문제가 아니라 구조체의 중복 선언이 문제
        • 이때 #ifndef __STDIV_H__ 를 사용해 조건부 컴파일을 사용하면 된다 (크게 의미없는 매크로를 사용한다)
        • ex) stdiv2.h 헤더파일 구현시
          • #ifndef __STDIV2_H__
          • #define__ STDIV2_H__
          • ~~ ~~ ~~
          • #endif
        • 를 사용해서 중복 삽입이 됬을 경우 컴파일이 되지 않게 선언해주면 된다(중복 선언은 되지만, 안에 내용이 없는 상태로 치환되기 때문에 문제가 발생하지 않음)