C의 아래 진술 중에서 어느 것이 더 나은가요?
static const int var = 5;
또는
#define var 5
또는
enum { var = 5 };
답변
필요한 가치에 따라 다릅니다. 당신 (그리고 지금까지 다른 사람들)은 세 번째 대안을 생략했습니다.
static const int var = 5;
#define var 5
enum { var = 5 };
이름 선택에 관한 문제를 무시하면 다음과 같습니다.
- 포인터를 주위에 전달해야하는 경우 (1)을 사용해야합니다.
- (2)는 분명히 옵션이므로 포인터를 전달할 필요가 없습니다.
- (1)과 (3) 모두 디버거의 심볼 테이블에 심볼이있어 디버깅이 쉬워집니다. (2)에 기호가 없을 가능성이 높으며 그 의미가 무엇인지 궁금해합니다.
- (1) 전역 범위에서 배열의 차원으로 사용할 수 없습니다. (2)와 (3) 모두 가능합니다.
- (1) 함수 범위에서 정적 배열의 차원으로 사용할 수 없습니다. (2)와 (3) 모두 가능합니다.
- C99에서는이 모든 것을 로컬 어레이에 사용할 수 있습니다. 기술적으로 (1)을 사용하는 것은 VLA (가변 길이 배열)를 사용한다는 것을 의미하지만 ‘var’이 참조하는 차원은 물론 크기 5로 고정됩니다.
- (1) 스위치 문과 같은 장소에서는 사용할 수 없습니다. (2)와 (3) 모두 가능합니다.
- (1) 정적 변수를 초기화하는 데 사용할 수 없습니다. (2)와 (3) 모두 가능합니다.
- (2) 전 처리기에서 사용하기 때문에 변경하고 싶지 않은 코드를 변경할 수 있습니다. (1)과 (3)은 모두 예상치 못한 부작용이 없습니다.
- 프리 프로세서에 (2)가 설정되어 있는지 여부를 감지 할 수 있습니다. (1)도 (3)도 허용하지 않습니다.
따라서 대부분의 상황에서 대안보다 ‘열거’를 선호합니다. 그렇지 않으면 첫 번째 글 머리 기호와 마지막 글 머리 기호가 제어 요소가 될 가능성이 높으며 한 번에 두 가지를 모두 만족시켜야하는 경우 더 열심히 생각해야합니다.
C ++에 대해 묻는다면 매번 옵션 (1) (정적 const)를 사용합니다.
답변
일반적으로 말하면:
static const
범위를 존중하고 형식이 안전하기 때문입니다.
내가 볼 수있는 유일한주의 사항 : 명령 줄에 변수를 정의하려는 경우. 여전히 대안이 있습니다.
#ifdef VAR // Very bad name, not long enough, too general, etc..
static int const var = VAR;
#else
static int const var = 5; // default value
#endif
가능하면 매크로 / 줄임표 대신 유형이 안전한 대안을 사용하십시오.
매크로와 함께 가야하는 경우 (예 : __FILE__
또는 __LINE__
) 매크로 이름을 매우 신중하게 지정하는 것이 좋습니다. 명명 규칙에서 Boost 는 프로젝트 이름으로 시작하는 모든 대문자를 권장합니다 (여기서는 BOOST_ ), 라이브러리를 숙독하는 동안 (일반적으로) 그 뒤에 특정 영역 (라이브러리)의 이름과 그 뒤에 의미있는 이름이 붙는 것을 알 수 있습니다.
그것은 일반적으로 긴 이름을 만듭니다 🙂
답변
C에서는 구체적으로? 사용 : C에서 정답은 #define
(해당되는 경우, 또는 enum
)
const
객체 의 범위 지정 및 타이핑 속성을 갖는 것이 유리하지만 , 실제로 const
C의 객체 (C ++와 반대)는 실제 상수가 아니므로 대부분의 실제 경우에는 쓸모가 없습니다.
따라서 C에서 선택은 상수를 어떻게 사용할 계획인지에 따라 결정되어야합니다. 예를 들어, const int
개체를 case
레이블 로 사용할 수 없습니다 (매크로가 작동하는 동안). const int
매크로를 작동하는 동안 객체를 비트 필드 너비로 사용할 수 없습니다 . C89 / 90에서는 const
객체를 사용하여 배열 크기를 지정할 수 없습니다 (매크로가 작동하는 동안). C99에서도 VLAconst
가 아닌 배열 이 필요할 때 객체를 사용하여 배열 크기를 지정할 수 없습니다 .
이것이 당신에게 중요하다면 그것은 당신의 선택을 결정할 것입니다. 대부분의 경우 #define
C 에서 사용하는 것 외에는 선택의 여지가 없습니다 enum
. C-에서 진정한 상수를 생성하는 다른 대안을 잊지 마십시오 .
C ++ const
객체는 진정한 상수이므로 C ++에서는 const
변형 을 선호하는 것이 거의 항상 좋습니다 ( static
C ++ 에서는 명시 적으로 필요하지 않음 ).
답변
차이 static const
하고 #define
있다는 이전의 메모리 사용 및 저장을 위해 나중에 사용하지 않는 메모리. 둘째,의 주소는 전달할 수 없지만의 주소 #define
는 전달할 수 있습니다 static const
. 실제로 그것은 우리가 어떤 환경에 있는지에 따라 다르며,이 두 가지 중에서 하나를 선택해야합니다. 둘 다 다른 상황에서 최선을 다하고 있습니다. 하나가 다른 것보다 낫다고 가정하지 마십시오 … 🙂
만약 그렇다면, Dennis Ritchie 는 최선을 다했을 것입니다 … hahaha … 🙂
답변
C #define
에서는 훨씬 더 인기가 있습니다. 예를 들어 배열 크기를 선언하기 위해 해당 값을 사용할 수 있습니다.
#define MAXLEN 5
void foo(void) {
int bar[MAXLEN];
}
ANSI C는 static const
내가 아는 한이 문맥에서 s 를 사용할 수 없습니다 . C ++에서는 이러한 경우 매크로를 피해야합니다. 당신은 쓸 수 있습니다
const int maxlen = 5;
void foo() {
int bar[maxlen];
}
static
내부 연결은 const
이미 [C ++에서만]에 의해 암시되기 때문에 제외하십시오 .
답변
const
C 의 또 다른 단점은 다른를 초기화 할 때 값을 사용할 수 없다는 것 const
입니다.
static int const NUMBER_OF_FINGERS_PER_HAND = 5;
static int const NUMBER_OF_HANDS = 2;
// initializer element is not constant, this does not work.
static int const NUMBER_OF_FINGERS = NUMBER_OF_FINGERS_PER_HAND
* NUMBER_OF_HANDS;
컴파일러는 상수로 간주하지 않기 때문에 const에서도 작동하지 않습니다.
static uint8_t const ARRAY_SIZE = 16;
static int8_t const lookup_table[ARRAY_SIZE] = {
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; // ARRAY_SIZE not a constant!
const
이 경우에는 타이핑을 사용하게되어 기쁩니다 . 그렇지 않으면 …
답변
도망 갈 수 있다면 static const
많은 장점이 있습니다. 일반적인 범위 원칙을 준수하고 디버거에서 볼 수 있으며 일반적으로 변수가 따르는 규칙을 따릅니다.
그러나 최소한 원래 C 표준에서는 실제로 일정하지 않습니다. 당신이 사용하는 경우 #define var 5
, 당신은 쓸 수 int foo[var];
선언으로,하지만 당신과 함께 컴파일러 확장 “를 제외하고 (그렇게 할 수 없습니다 static const int var = 5;
. 이것은 ++은 C의 경우가 아니라 static const
버전 어디서나 사용할 수 있습니다#define
버전 캔, 그리고 믿을 C99의 경우도 마찬가지입니다.
그러나 #define
소문자 이름 으로 상수 이름을 지정하지 마십시오 . 번역 단위가 끝날 때까지 해당 이름을 사용할 수 있습니다. 매크로 상수는 사실상 고유의 네임 스페이스에 있어야하며, 일반적으로 접두사가있는 모든 대문자입니다.