프로그래밍/C2011. 11. 28. 14:48

(참조: C언어 펀더멘탈, 전웅 저, 한빛 미디어)


이놈은 농담이고, 열거자에 대한 여러가지 알아야 할 것들을 적어 보았다.


동일한 값을 나타내도록 선언 할 수 있음

    enum food { apple = 2, orange = 2, banana = 2 };


대소관계를 순서로 가질 필요도 없음

    enum food { apple = 2, orange = 3, banana = 1};


열거상수로 선언되는 명칭은 일반 명칭과 동일한 이름 공간을 사용

    enum food { apple = 2, orange = 3, banana = 4};

    int apple; /* wrong */


값이 지정되어 있지 않은 경우,

첫번째 열거자면 0으로 값을 갖는다

첫번째가 아니라면 앞의 값보다 하나 큰 값을 가진다.


열거형에는 불완전형의 개념이 존재하지 않는다.

    enum food *p; /* wrong */

    enum food;     /* wrong */


열거형을 위해 사용할 정수형은 다음과 같다.

(signed/unsigned) char

signed/unsigned short int

signed/unsigned int

signed/unsigned long int


열거의 올바른 사용법

가장 올바르게 열거를 사용하기 위해서는 열거를 마치 구조체나 공용체처럼 완전히 독립된 데이터형으로 다루어야 한다. 그러기 위해선, 다음과 같이...

  • 열거형 대상체에는 반드시 그 열거형이 멤버로 갖는 열거 상수만을 대입한다.
  • 열거형 대상체를 다른 정수형의 값과 함께 연산에 사용하는 경우, 반드시 적절한 캐스트 연산자와 주석을 통해 의도를 분명히 밝힌다.
  • 열거형 대상체에 해당 열거형의 열거 상수가 아닌 임의의 정수값을 대입할 필요가 있다면, 그 정수값을 열거형의 멤버로 추가하는 것을 고려한다.
  • 서로 다른 열거형 사이에 대입이나 연산은 피한다.



Posted by code cat
프로그래밍/C2011. 11. 9. 10:26

출처: C 언어 펀더멘탈, 전웅 저, 한빛미디어

#define int2hex(n) ((int)"0123456789ABCDEF"[(int)(n)])


int (int2hex)(int n)

{

    return "012345678ABCDEF"[n];

}


(int2hex)를 괄호로 둘러쌓아, 만일

int int2hex(int n)

으로 함수를 정의했을 때 매크로로 확장되는 걸 방지 할 수 있다.  함수의 주소를 취할 때도 함수명만 사용하거나 함수명에 번지 연산자를  붙인 형태를 사용하기 때문에 전처리 과정에서 매크로로 확장되지 않는다.

만약 필요에 따라 매크로가 아닌 실제 함수를 호출하고 싶다면, #undef 지시자를 사용하거나 다음과 같은 형태의 함수 호출 수식을 사용할 수 있다.

(int2hex)(12);


한편 매크로 함수를 사용하는 또 다른 경우는, 이미 구현되어 있는 함수에서 일정 개수의 인자를 특정 값으로 고정해 사용하는 경우이다.  특히 이는 라이브러리를 구현할 때 많이 사용하는 방법이다.  예를 들어 line()이라는 함수가 구현되어 있다고 하자.

#define line_h(x, y, len, c, s) (line((x),(y),(x)+(len)-1, (y),(c),(s)))

#define line_v(x, y, len, c, s) (line((x),(y),(x),(y)+(len)-1,(c),(s)))

등으로 간단히 매크로로 대체할 수 있다.


여러 수식을 하나의 수식으로 만들어 매크로 함수에 담는 것은 쉼표 연산자를 사용하면 간단하다.  특히 쉼표 연산자는 피연산자로 주어진 수식 사이에서 평가순서와 시퀀스 포인트를 보장해 주기 때문에 연속적인 수식문과 동일하게 사용된다.

#define func_seq() (func1(a,b,c,d),\

    func2(a,b,c,d),\

    func3(a,b,c,d))


매크로 함수 사용시에 세미콜론의 사용여부를 다음과 같이 간단히 처리 할 수 있다.

#define SMT(test, ret) \

    do{                       \

     if(!(test)){             \

        set_error(SMT_ERROR); \

        return ret;

    }

}while(0)

Posted by code cat
프로그래밍/C2011. 10. 23. 14:51
구조체 멤버로 주소를 저장하기 위해서는 구조체 멤버를 포인터 변수로 선언하라
구조체 멤버로 연속적인 메모리를 만들기 위해서는 구조체 멤버를 배열로 선언하라
 

'프로그래밍 > C' 카테고리의 다른 글

process & signal  (0) 2012.01.25
error: invalide storage class for function 'xxxx'  (0) 2011.11.29
대상체의 기억수명  (0) 2011.11.29
열거, enum, 이놈  (0) 2011.11.28
전처리기 (1)  (0) 2011.11.09
Posted by code cat