노동 조합은 언제 사용해야합니까? 왜 필요한가요?
답변
정수는 종종 이진 표현의 정수와 부동 소수점 사이를 변환하는 데 사용됩니다.
union
{
int i;
float f;
} u;
// Convert floating-point bits to integer:
u.f = 3.14159f;
printf("As integer: %08x\n", u.i);
이것은 C 표준에 따라 기술적으로 정의되지 않은 동작이지만 (가장 최근에 작성된 필드 만 읽어야 함) 거의 모든 컴파일러에서 잘 정의 된 방식으로 작동합니다.
또한 유니온은 C에 의사 다형성을 구현하는 데 사용됩니다. 구조체에 포함 된 객체의 유형을 나타내는 태그를 제공 한 다음 가능한 유형을 함께 결합하여 다음과 같습니다.
enum Type { INTS, FLOATS, DOUBLE };
struct S
{
Type s_type;
union
{
int s_ints[2];
float s_floats[2];
double s_double;
};
};
void do_something(struct S *s)
{
switch(s->s_type)
{
case INTS: // do something with s->s_ints
break;
case FLOATS: // do something with s->s_floats
break;
case DOUBLE: // do something with s->s_double
break;
}
}
따라서 크기 struct S
가 28이 아니라 12 바이트 만됩니다.
답변
유니온은 임베디드 프로그래밍 또는 하드웨어 / 메모리에 직접 액세스해야하는 상황에서 특히 유용합니다. 다음은 간단한 예입니다.
typedef union
{
struct {
unsigned char byte1;
unsigned char byte2;
unsigned char byte3;
unsigned char byte4;
} bytes;
unsigned int dword;
} HW_Register;
HW_Register reg;
그런 다음 다음과 같이 reg에 액세스 할 수 있습니다.
reg.dword = 0x12345678;
reg.bytes.byte3 = 4;
엔디안 (바이트 순서) 및 프로세서 아키텍처는 물론 중요합니다.
또 다른 유용한 기능은 비트 수정 자입니다.
typedef union
{
struct {
unsigned char b1:1;
unsigned char b2:1;
unsigned char b3:1;
unsigned char b4:1;
unsigned char reserved:4;
} bits;
unsigned char byte;
} HW_RegisterB;
HW_RegisterB reg;
이 코드를 사용하면 레지스터 / 메모리 주소에서 단일 비트에 직접 액세스 할 수 있습니다.
x = reg.bits.b2;
답변
저수준 시스템 프로그래밍은 합리적인 예입니다.
IIRC, 유니온을 사용하여 하드웨어 레지스터를 구성 요소 비트로 분해했습니다. 따라서 구성 요소 비트에 8 비트 레지스터에 액세스 할 수 있습니다.
(정확한 구문은 잊었지만 …)이 구조를 통해 제어 레지스터를 control_byte 또는 개별 비트를 통해 액세스 할 수 있습니다. 주어진 엔디안에 대해 비트가 올바른 레지스터 비트에 매핑되도록하는 것이 중요합니다.
typedef union {
unsigned char control_byte;
struct {
unsigned int nibble : 4;
unsigned int nmi : 1;
unsigned int enabled : 1;
unsigned int fired : 1;
unsigned int control : 1;
};
} ControlRegister;
답변
나는 객체 지향 상속을 대체하는 것으로 두 개의 라이브러리에서 그것을 보았습니다.
예 :
Connection
/ | \
Network USB VirtualConnection
Connection “클래스”가 위 중 하나가되도록하려면 다음과 같이 작성할 수 있습니다.
struct Connection
{
int type;
union
{
struct Network network;
struct USB usb;
struct Virtual virtual;
}
};
libinfinity에서의 사용 예 : http://git.0x539.de/?p=infinote.git;a=blob;f=libinfinity/common/inf-session.c;h=3e887f0d63bd754c6b5ec232948027cbbf4d61fc;hb=HEAD#l74
답변
통합은 상호 배타적 인 데이터 멤버가 동일한 메모리를 공유 할 수 있도록합니다. 이것은 임베디드 시스템과 같이 메모리가 부족한 경우 매우 중요합니다.
다음 예에서
union {
int a;
int b;
int c;
} myUnion;
이 공용체는 3 개의 개별 int 값이 아닌 단일 int의 공간을 차지합니다. 사용자의 값으로 설정하면 을 다음의 설정 값 B를 , 그것의 값을 덮어 쓰기 을 이들이 모두 동일한 메모리 위치를 공유하기 때문이다.
답변
많은 사용법. 그냥 grep union /usr/include/*
또는 비슷한 디렉토리에 있습니다. 대부분의 경우에 union
래핑되어 있고 struct
구조체의 한 멤버는 공용체의 어느 요소에 액세스 할 수 있는지 알려줍니다. man elf
실제 구현을위한 체크 아웃 을 예로들 수 있습니다.
이것이 기본 원칙입니다.
struct _mydata {
int which_one;
union _data {
int a;
float b;
char c;
} foo;
} bar;
switch (bar.which_one)
{
case INTEGER : /* access bar.foo.a;*/ break;
case FLOATING : /* access bar.foo.b;*/ break;
case CHARACTER: /* access bar.foo.c;*/ break;
}
답변
다음은 내 자신의 코드베이스 (메모리 및 구문이 정확하지 않을 수 있음)의 통합 예입니다. 내가 작성한 인터프리터에 언어 요소를 저장하는 데 사용되었습니다. 예를 들어, 다음 코드는
set a to b times 7.
다음 언어 요소로 구성됩니다.
- 상징 [세트]
- 변수 [a]
- 기호 [to]
- 변수 [b]
- 상징 [시간]
- 상수 [7]
- 상징[.]
언어 요소는 ‘ #define
‘값 으로 정의되었습니다 .
#define ELEM_SYM_SET 0
#define ELEM_SYM_TO 1
#define ELEM_SYM_TIMES 2
#define ELEM_SYM_FULLSTOP 3
#define ELEM_VARIABLE 100
#define ELEM_CONSTANT 101
다음 구조를 사용하여 각 요소를 저장했습니다.
typedef struct {
int typ;
union {
char *str;
int val;
}
} tElem;
각 요소의 크기는 최대 합집합의 크기였습니다 (일반적인 값이지만 실제 크기는 구현에 따라 다름).
“set”요소를 작성하려면 다음을 사용하십시오.
tElem e;
e.typ = ELEM_SYM_SET;
“variable [b]”요소를 작성하려면 다음을 사용하십시오.
tElem e;
e.typ = ELEM_VARIABLE;
e.str = strdup ("b"); // make sure you free this later
“constant [7]”요소를 작성하려면 다음을 사용하십시오.
tElem e;
e.typ = ELEM_CONSTANT;
e.val = 7;
float ( float flt
) 또는 rationals ( struct ratnl {int num; int denom;}
) 및 기타 유형 을 포함하도록 쉽게 확장 할 수 있습니다 .
기본 전제는 점이다 str
및 val
그 구조는 메모리 위치에 기초하고, 여기서 도시 된 동일한 메모리 블록에 다른 뷰를 얻는 방법 그래서 그들은 오버랩 실제로 메모리에 인접하지 않은 0x1010
및 정수 및 포인터 모두이다 4 바이트:
+-----------+
0x1010 | |
0x1011 | typ |
0x1012 | |
0x1013 | |
+-----+-----+
0x1014 | | |
0x1015 | str | val |
0x1016 | | |
0x1017 | | |
+-----+-----+
구조에 있다면 다음과 같습니다.
+-------+
0x1010 | |
0x1011 | typ |
0x1012 | |
0x1013 | |
+-------+
0x1014 | |
0x1015 | str |
0x1016 | |
0x1017 | |
+-------+
0x1018 | |
0x1019 | val |
0x101A | |
0x101B | |
+-------+