대부분의 C개발자가 const 대신 정의를 사용하는 이유는 무엇입니까?
많은 프로그램에서#define
상수와 같은 목적으로 기능합니다.예를들면.
#define FIELD_WIDTH 10
const int fieldWidth = 10;
기본적으로 애플리케이션 결정을 처리하기 위해 프리프로세서에 의존하는 첫 번째 폼이 다른 폼보다 더 선호된다는 것을 흔히 볼 수 있습니다.이 전통에 이유가 있나요?
여기에는 매우 확실한 이유가 있습니다.const
C에서 무엇인가가 일정하다는 것을 의미하지 않습니다.변수가 읽기 전용이라는 의미일 뿐입니다.
컴파일러가 진정한 정수를 필요로 하는 장소(VLA 이외의 어레이의 어레이 크기 등)에서는const
변수(예:fieldWidth
불가능할 뿐이죠
그들은 다르다.
const
는 실행 시 변수를 변경할 수 없음을 나타내는 한정자일 뿐입니다.그러나 변수의 다른 모든 기능은 지속됩니다. 즉, 스토리지가 할당되어 있기 때문에 이 스토리지는 처리될 수 있습니다.따라서 코드는 단순히 리터럴로 취급하는 것이 아니라 지정된 메모리 위치에 액세스하여 변수를 참조합니다(단, 이 위치가 다음과 같은 경우는 제외).static const
최적화할 수 있습니다.) 및 런타임에 해당 값을 로드합니다.그리고...const
변수가 스토리지를 할당했습니다. 헤더에 추가하여 여러 C 소스에 포함시키면 "복수 기호 정의" 링크 오류가 발생합니다.extern
이 경우 컴파일러는 코드를 실제 값과 비교하여 최적화할 수 없습니다(글로벌 최적화가 켜져 있지 않은 경우).
#define
는 단순히 이름을 값으로 대체합니다.또,#define
'd 상수는 프리프로세서로 사용할 수 있습니다.#ifdef
값을 기준으로 조건부 컴파일을 수행하거나 문자열화 연산자를 사용합니다.#
값을 가진 문자열을 얻습니다.컴파일러는 컴파일 시에 그 값을 알고 있기 때문에 그 값을 바탕으로 코드를 최적화할 수 있습니다.
예를 들어 다음과 같습니다.
#define SCALE 1
...
scaled_x = x * SCALE;
언제SCALE
로 정의됩니다.1
컴파일러는 그것을 알고 있기 때문에 곱셈을 제거할 수 있다.x * 1 == x
단,SCALE
는 ( 입니다.extern
)const
값은 링크 단계까지 알 수 없기 때문에 값을 가져오고 곱셈을 수행하기 위해 코드를 생성해야 합니다.(extern
여러 소스 파일의 상수를 사용하려면 이 필요합니다.)
사용하는 것과 거의 동등합니다.#define
는 열거를 사용하고 있습니다.
enum dummy_enum {
constant_value = 10010
};
그러나 이는 정수값으로 제한되며 다음과 같은 장점이 없습니다.#define
, 그래서 널리 사용되지 않습니다.
const
는 상수 값을 컴파일된 라이브러리에서 Import해야 할 때 유용합니다.또는 포인터와 함께 사용되는 경우.또는 변수 인덱스 값을 통해 액세스하는 상수 값의 배열인 경우.그렇지않으면,const
에 비해 이점이 없다#define
.
C에서 숫자 상수를 정의하는 가장 좋은 방법은 열거형을 사용하는 것입니다.K&R의 The C Programming Language(39페이지)의 해당 장을 읽으십시오.
그 이유는 대부분의 경우 상수를 원하기 때문이지const
- 수식 변수.이 두 가지는 C 언어에서 전혀 동일하지 않습니다.예를 들어 변수는 다음에 대한 이니셜라이저의 일부로 사용할 수 없습니다.static
vla 이외의 어레이 치수(예를 들어 구조 내의 어레이 크기 또는 C99보다 이전 어레이)의 스토리지 기간 객체.
K&R (제2판, 211페이지)에 따르면, "항상 휘발성이 있는 속성은 ANSI 표준에 의해 새로운 것입니다."이것은 매우 오래된 ANSI 코드에는 이러한 키워드가 전혀 없고, 단지 전통의 문제일 뿐이라는 것을 의미할 수 있습니다.게다가 컴파일러는 const 변수를 변경하려는 시도를 검출해야 하지만, 그 외에는 이러한 한정자를 무시할 수 있다고 합니다.즉, 일부 컴파일러는 const 변수를 포함하는 코드를 기계 코드로 중간값으로 표시하지 않을 수 있으며(#define처럼), 이는 원거리 메모리에 액세스하여 성능에 영향을 미칠 수 있습니다.
R의 답변을 조금 더 자세히 설명하겠습니다.fieldWidth
일정한 표현이 아니라const
- 수식 변수.이 값은 런타임까지 확립되지 않으므로 컴파일 시 상수식이 필요한 경우(예: 어레이 선언 또는 대/소문자 레이블)에는 사용할 수 없습니다.switch
기재 등)
매크로와 비교FIELD_WIDTH
전처리 후 상수 표현으로 확장됩니다.10
; 이 값은 컴파일 시에 알려져 있기 때문에 어레이 치수, 케이스 라벨 등에 사용할 수 있습니다.
R.과 Bart의 답변에 덧붙이자면, C에 심볼릭 컴파일 시간 상수를 정의하는 방법은 오직 한 가지뿐입니다. 열거형 상수입니다.표준에서는 이것들이 형식이라고 규정하고 있다.int
저는 개인적으로 당신의 예를 다음과 같이 쓰고 싶습니다.
enum { fieldWidth = 10 };
근데 그 맛은 C프로그래머들마다 많이 다른 것 같아요
const int가 항상 적절한 것은 아니지만 정수값으로 정의하는 경우에는 보통 #define 대신 enum이 기능합니다.이런 경우에는 사실 이게 제 취향입니다.
enum { FIELD_WIDTH = 16384 };
char buf[FIELD_WIDTH];
C++에서는 클래스 또는 네임스페이스에서 열거형의 범위를 지정할 수 있지만 #define의 범위를 지정할 수 없기 때문에 큰 이점이 있습니다.
C에는 네임스페이스도 없고 구조체 내의 열거형도 스코프할 수 없습니다.또한 타입의 안전성을 얻을 수 있는지조차 확신할 수 없기 때문에, 거기에 있는 C프로그래머가 지적해 줄지도 모르지만, 실제로는 큰 메리트를 알 수 없습니다.
일부 C 컴파일러는 모든 것을 저장합니다.const
2진수 내의 변수, 즉 대량의 계수 목록을 준비하는 경우 임베디드 월드에서 엄청난 공간을 사용할 수 있습니다.
반대로: 사용const
기존 프로그램을 플래시하여 특정 파라미터를 변경할 수 있습니다.
언급URL : https://stackoverflow.com/questions/4024318/why-do-most-c-developers-use-define-instead-of-const
'IT이야기' 카테고리의 다른 글
vuejs + babel-intered 이거.setDynamic은 함수가 아닙니다. (0) | 2022.06.03 |
---|---|
Nuxt 저장소 변환이 TypeError를 수신했습니다. (0) | 2022.06.03 |
Laravel에서 Vue.js를 운영 모드로 전환하는 방법 (0) | 2022.06.02 |
C에서 오브젝트 파일을 링크하려면 어떻게 해야 하나요?"아키텍처 x86_64에 대한 정의되지 않은 기호"에서 실패함 (0) | 2022.06.02 |
사물의 깊은 복사는 어떻게 합니까? (0) | 2022.06.02 |