두 개의 다른 열거형-정수 값이 동일한 이유는 무엇인가?
내가 이렇게 열거형 평일을 정의한다면:
enum weekday {
MON,
TUE,
WED,
THU,
FRI,
};
그러면 기본적으로 MON은 내부적으로 0, TUE는 1, WED는 2...
하지만 내가 이것을 이렇게 정의한다면:
enum weekday {
MON,
TUE = 0,
WED,
THU,
FRI,
};
그럼 둘 다MON
그리고TUE
0이라는 값을 얻을 수 있을 것이다.
시스템이 내부적으로 MON과 TUE를 어떻게 구별할 것인가?내 말은, 만약 내가 이런걸 선언한다면:
enum weekday today = 0;
그럼 오늘인가?MON
또는TUE
아니면, 철학적으로 말하면, 둘 다?
C 열거형은 "진짜" 정수로, 우연히 그렇게 구현되었기 때문만이 아니라, 표준이 열거형을 정수 값으로 정의하기 때문이다.그래서 그 가치는today
"진짜" 0. 0이라는 값에 대해 두 개의 다른 이름을 만든 것뿐입니다.
그렇다면 "오늘은 MON인가 TUE인가"에 대한 대답은 "예" ;-)라고 생각한다.
언어는 때때로 열거형이 동일한 값에 대해 여러 개의 이름을 갖는 것이 유용하기 때문에 당신을 멈추게 하지 않는다.예를 들면 다음과 같다.
enum compression_method {
COMP_NONE = 0,
COMP_LOW = 1,
COMP_HIGH = 2,
COMP_BEST = 2,
COMP_FASTEST = 0,
};
두 개의 다른 열거형 정수가 동일한 정수 값을 가질 수 있는 이유는 무엇인가?
6.7.2.2/3 "누적 지정자"에서 N1265 C99 표준 초안에 명시적으로 허용되기 때문에:
에 대한 열거자 사용
=
동일한 열거에서 다른 값을 중복하는 값을 가진 열거 상수를 생성할 수 있다.
시스템이 내부적으로 MON과 TUE를 어떻게 구별할 것인가?
나는 그것이 시간 상수(6.6/6 "정수 표현")이기 때문에 불가능하다고 생각한다.그 결과, 다음과 같다.
편찬 후에 다른 것으로 수정될 수 없다.
그들을 구분할 주소가 없다.C에서 열거값의 메모리 위치
컴파일 시간 상수는 당신이 수정할 수 없는 것에는 주소를 사용할 수 없기 때문에 어떤 주소도 필요하지 않다.
GCC는 단순히 열거형 구성원의 사용을 컴파일 시 조립의 즉각적인 값으로 대체한다.고려 사항:
#include <stdio.h>
enum E {
E0 = 0x1234,
E1 = 0x1234
};
int i = 0x5678;
int main() {
printf("%d\n", E0);
printf("%d\n", E1);
printf("%d\n", i);
return 0;
}
GCC 4.8 x86_64로 컴파일 및 디컴파일:
gcc -c -g -O0 -std=c89 main.c
objdump -Sr main.o
출력에 포함되는 내용:
printf("%d\n", E0);
4: be 34 12 00 00 mov $0x1234,%esi
...
printf("%d\n", E1);
18: be 34 12 00 00 mov $0x1234,%esi
...
printf("%d\n", i);
2c: 8b 05 00 00 00 00 mov 0x0(%rip),%eax # 32 <main+0x32>
2e: R_X86_64_PC32 i-0x4
32: 89 c6 mov %eax,%esi
그래서 우리는 다음과 같이 본다.
- 열거된 회원들은 즉시 사용되어진다.
$0x1234
그래서 그들이 어디서 왔는지 아는 것은 불가능하다. - 변수
i
그러나 기억에서 우러나온다.0x0(%rip)
(이전 예정) 두 변수를 주소별로 구분할 수 있도록
단지 다른 답변들을 보완하기 위해, 나는 당신에게 주어진 다른 열거에 대해 같은 값을 어떻게 사용하는지에 대한 실용적인 예를 제시하겠다.enum
널리 유용하다:
enum slots_t {
SLOT_FIRST = 0,
SLOT_LEFTARM = SLOT_FIRST,
SLOT_RIGHTARM = 1,
SLOT_TORSO = 2,
SLOT_LEFTLEG = 3,
SLOT_RIGHTLEG = 4,
SLOT_LAST = SLOT_RIGHTLEG
};
그러면 코드대로 할 수 있다.
for (int i = SLOT_FIRST; i <= SLOT_LAST; ++i) { }
마치 철학적(또는 그렇지 않은) 것 같다.
#define ZILCH 0
#define NADA 0
서로 다른 이름을 갖는 것이 같은 숫자로 귀결되는 것이 말이 되는 많은 용도가 있다.
열거 상수의 이름은 실제 값 자체가 아니라 값을 할당하는 데 사용된다.만약 당신이 오늘 0 값을 할당한다면, 출력 값은 0이 될 것이다.그리고 예, MON과 TUE 모두 값이 0이고 나머지 값은 WED=1 THU=2 등으로 할당된다.
'Programing' 카테고리의 다른 글
Vue.js 패스 슬롯과 래핑된 Bootstrap-Vue Table 구성 요소 연결 (0) | 2022.05.20 |
---|---|
C 프로그램 설계 학습을 위한 리소스 (0) | 2022.05.20 |
Java에서 문자열을 int로 변환하는 방법 (0) | 2022.05.20 |
vuetify의 확장 패널 문제를 해결하는 방법 (0) | 2022.05.20 |
Java에서 이중 형식을 지정하는 문자열.format() (0) | 2022.05.20 |