C 언어 프로 그래 밍 기법 은 const 와\#define 의 차이 점 에 대한 소감

4255 단어 const#define
#define ASPECT_RATIO 1.653 컴 파일 러 는 영원히 ASPECT 를 볼 수 없습니다.RATIO 라 는 기호 명 은 원본 코드 가 컴 파일 러 에 들 어가 기 전에 예비 처리 프로그램 에 의 해 제거 되 기 때문에 ASPECTRATIO 는 기호 목록 에 가입 하지 않 습 니 다.이 상수 와 관련 된 코드 가 타 임 스 를 컴 파일 하 는 데 잘못 되 었 다 면 이해 하기 어 려 울 것 입 니 다.잘못된 정 보 는 ASPECT 가 아 닌 1.653 을 말 하기 때 문 입 니 다.RATIO。하면,만약,만약...RATIO 는 자신 이 쓴 헤더 파일 에서 정 의 된 것 이 아니 라 1.653 이 어디서 왔 는 지 이상 하 게 생각 하고 추적 하 는 데 시간 이 걸 릴 수도 있다.이 문 제 는 기호 디 버 거 에 도 나타 날 수 있 습 니 다.마찬가지 로 기호 이름 이 기호 목록 에 나타 나 지 않 기 때 문 입 니 다.이 문 제 를 해결 하 는 방안 은 매우 간단 합 니 다.매크로 를 미리 처리 하지 않 고 상수 로 정의 합 니 다. 
const double ASPECT_RATIO = 1.653;
이런 방법 은 매우 효과 가 있다.하지만 두 가지 특별한 상황 이 있 습 니 다.
우선 포인터 상수 가 다 를 수 있 습 니 다.상수 정 의 는 일반적으로 헤더 파일 에 놓 여 있 기 때문에(허 다 원 파일 은 이 를 포함 합 니 다)포인터 가 가리 키 는 형식 을 const 로 정의 하 는 것 을 제외 하고 중요 한 것 은 포인터 도 항상 const 로 정의 해 야 합 니 다.예 를 들 어 헤더 파일 에서 char*기반 문자열 상수 를 정의 하려 면 const 를 두 번 써 야 합 니 다.
const char * const authorName = "Scott Meyers";
const 의 의미 와 용법,특히 지침 과 관련 된 문제 에 대해 서 는 조항 21 을 참조 합 니 다. 
또한 특정한 클래스(class)를 정의 하 는 상수 도 일반적으로 편리 하고 조금 만 다르다.상수 를 클래스 로 제한 하려 면 먼저 클래스 의 구성원 이 되 어야 한다.상수 가 최대 1 부 만 복사 되도록 정적 구성원 으로 정의 합 니 다.      
class GamePlayer { private: static const int NUM_TURNS = 5; // constant eclaration  int scores[NUM_TURNS]; // use of constant ... };
또 하 나 는 보시 다시 피 위의 문 구 는 NUM 입 니 다.TURNS 의 성명 은 정의 가 아니 므 로 클래스 구현 코드 파일 에서 클래스 의 정적 구성원 을 정의 해 야 합 니 다.
const int GamePlayer::NUM_TURNS; // mandatory definition; // goes in class impl.file
너 는 이런 작은 일 을 지나치게 걱정 할 필요 가 없다.정 의 를 잊 어 버 리 면 링크 가 알려 줍 니 다.
오래된 컴 파일 러 는 이러한 문법 을 받 아들 이지 않 습 니 다.왜냐하면 이러한 정적 구성원 이 성명 할 때 초기 값 을 정의 하 는 것 이 불법 이 라 고 생각 하기 때 문 입 니 다.그리고 클래스 에 서 는 정수 형식(예 를 들 어 int,bool,char 등)만 초기 화 할 수 있 고 상수 일 수 있 습 니 다.위의 문법 을 사용 할 수 없 는 경우 정의 할 때 초기 값 을 부여 할 수 있 습 니 다:class Engineering Constants{/this goes in the class private:/header file static const double FUDGEFACTOR; ... }; // this goes in the class implementation file const double EngineeringConstants::FUDGE_FACTOR = 1.35;
대부분의 경우 너 는 이렇게 만 하면 된다.유일한 예 외 는 클래스 가 컴 파일 할 때 이러한 상수 가 필요 한 경우 입 니 다.예 를 들 어 위의 GamePlayer:scores 배열 의 성명(컴 파일 과정 에서 컴 파일 러 는 배열 의 크기 를 알 아야 합 니 다).따라서 클래스 내 에서 정형 류 상수 초기 화 를 금지 하 는 컴 파일 러 의 부족 을 보완 하기 위해'enum'이 라 고 부 르 는 방법 으로 해결 할 수 있다.이 기술 은 int 형식 이 필요 할 때 매 거 진 형식 을 사용 할 수 있다 는 원칙 을 잘 이용 하기 때문에 GamePlayer 도 이렇게 정의 할 수 있 습 니 다:class GamePlayer{private:enum{NUMTURNS = 5 } // "the enum hack" ― makes // NUM_TURNS a symbolic name  // for 5 int scores[NUM_TURNS];// fine };
오래된 컴 파일 러 를 사용 하고 있 지 않 으 면 enum 을 빌 릴 필요 가 없습니다.물론 이런 방법 이 있다 는 것 을 아 는 것 은 가치 가 있 습 니 다.아주 오래된 시대 로 거 슬러 올 라 갈 수 있 는 코드 는 흔 하지 않 기 때 문 입 니 다.
예 처리 의 화제 로 돌아가다.또 하나의 보편적 인\#define 명령 의 용법 은 함수 처럼 보이 지만 함수 가 호출 되 지 않 는 매크로 를 실현 하 는 것 입 니 다.전형 적 인 예 는 두 대상 의 최대 치 를 계산 하 는 것 이다.\#define max(a,b)(a)>(b)?(a) : (b))
이 문 구 는 결함 이 많아 생각 만 해도 골 치 아 프 고 심지어 러시아워 에 고속도로 로 운전 하 는 것 보다 더 고통스럽다.언제든지 당신 이 이와 같은 매크로 를 썼 을 때,매크로 를 쓸 때 모든 매개 변수 에 괄호 를 넣 어야 한 다 는 것 을 기억 해 야 합 니 다.그렇지 않 으 면 다른 사람 이 당신 의 매크로 를 호출 할 때 표현 식 을 사용 하면 큰 문 제 를 일 으 킬 수 있 습 니 다.그러나 당신 이 이렇게 하 더 라 도 아래 와 같은 이상 한 일이 발생 할 수 있 습 니 다.
int a = 5, b = 0; max(++a, b);// a 의 값 이 max(+a,b+10)2 회 증가 합 니 다.//a 의 값 이 1 회 증가 하 였 습 니 다.
이런 상황 에서 max 내부 에서 무슨 일이 발생 하 는 지 는 그것 이 비교 하 는 값 에 달 려 있 습 니 다!다행히 너 는 더 이상 이런 어 리 석 은 말 을 참 을 필요 가 없다.일반 함수 로 매크로 의 효율 을 실현 할 수 있 습 니 다.게다가 예상 가능 한 행동 과 유형 안전 도 있 습 니 다.이것 이 바로 내 연 함수(조항 33 참조)입 니 다.inline int max(int a,int b){return a>b?a : b; } 그러나 이것 은 위의 매크로 와 다르다.왜냐하면 이 버 전의 max 는 int 형식 만 처리 할 수 있 기 때문이다.그러나 템 플 릿 은 이 문 제 를 쉽게 해결 할 수 있 습 니 다.templateinline const T&max(const T&a,const T&b){return a>b?a : b; }
이 템 플 릿 은 한 세트의 함 수 를 만 들 었 습 니 다.각 함 수 는 두 개의 같은 유형의 대상 으로 비교 한 다음 에 비교적 큰(상수)대상 의 인용 을 되 돌려 줍 니 다.T 의 유형 을 모 르 기 때문에 되 돌아 갈 때 인용 을 전달 하면 효율 을 높 일 수 있다(조항 22 참조).
참고 로 max 와 같은 유용 한 유 니 버 설 함 수 를 템 플 릿 으로 쓰 려 고 할 때 먼저 표준 라 이브 러 리(조항 49 참조)를 확인 하고 그들 이 이미 존재 하 는 지 확인 하 세 요.예 를 들 어 위 에서 말 한 max 는 후세 사람들 이 더 위 를 식 힐 수 있다 는 것 을 깜짝 발견 할 수 있 습 니 다.max 는 C+표준 라 이브 러 리 의 일부분 입 니 다.const 와 inline 이 있 으 면 예비 처리 에 대한 수요 가 줄 어 들 지만 전혀 없 을 수 는 없습니다.버 릴 날 은 아직 멀 었 습 니 다.\#ifdef/\#ifndef 는 컴 파일 을 제어 하 는 과정 에서 중요 한 역할 을 합 니 다.예비 처 리 는 아직 퇴직 할 수 없 지만,너 는 반드시 그것 에 게 자주 연 휴 를 보 낼 계획 을 세 워 야 한다.

좋은 웹페이지 즐겨찾기