C에서의 유니온의 예
저는 노조의 예를 찾고 있습니다. 노조가 어떻게 돌아가는지 이해하기 위해서가 아니라, 바라건대, 제가 이해하기 위해서입니다. 사람들이 노조를 가지고 어떤 해킹을 하는지 보기 위해서요.
그러니 자유롭게 당신의 유니온 해킹을 공유하세요 (물론 약간의 설명과 함께) :)
단순한 가상 시스템의 핵심처럼 "알 수 없는" 유형의 값을 나타내는 것이 고전입니다.
typedef enum { INTEGER, STRING, REAL, POINTER } Type;
typedef struct
{
Type type;
union {
int integer;
char *string;
float real;
void *pointer;
} x;
} Value;
이를 사용하면 스택 구현 등과 같이 정확한 유형을 알지 못한 채 "값"을 처리하는 코드를 작성할 수 있습니다.
C11 에, (이전, C11 이전) C에서 .struct
C++에서 당신은 다음과 같이 할 수 있습니다.union
이 을 선택하는 수 .이 이름을 선택하는 것은 어려울 수 있습니다.저는 한 글자로 된 것을 사용하는 경향이 있습니다. 왜냐하면 그것은 거의 단 한 글자로 언급되지 않기 때문에 항상 상황에서 무슨 일이 일어나고 있는지 명확하기 때문입니다.
값을 정수로 설정하는 코드는 다음과 같습니다.
Value value_new_integer(int integer)
{
Value v;
v.type = INTEGER;
v.x.integer = integer;
return v;
}
여기서 나는 그 사실을 사용합니다.struct
는 직접될 수 , 의 값과 유사하게 될 수 .struct
유니언은 컴파일러 및 인터프리터와 같은 언어 프로세서의 어휘 분석 및 구문 분석 단계에서도 일반적으로 사용됩니다.여기 제가 지금 편집하고 있는 것이 있습니다.
union {
char c;
int i;
string *s;
double d;
Expression *e;
ExpressionList *el;
fpos_t fp;
}
유니언은 의미론적 값을 어휘 분석기의 토큰 및 파서의 생산과 연결하는 데 사용됩니다.이 관행은 yacc와 같은 문법 생성기에서 매우 흔하며, yacc는 이를 명시적으로 지원합니다.조합은 모든 가치를 보유할 수 있지만, 한 번에 하나만 보유할 수 있습니다.예를 들어, 입력 파일의 어느 한 지점에서 문자 상수를 읽었거나(저장됨)c
됨)i
번호됨)d
). 는 처리 한하는 데 문법 생성기는 처리 중인 규칙에 따라 한 번에 저장되는 값을 결정하는 데 상당한 도움을 제공합니다.
여기 제가 매일 사용하는 작은 것이 있습니다.
struct tagVARIANT {
union {
struct __tagVARIANT {
VARTYPE vt;
WORD wReserved1;
WORD wReserved2;
WORD wReserved3;
union {
LONG lVal; /* VT_I4 */
BYTE bVal; /* VT_UI1 */
SHORT iVal; /* VT_I2 */
FLOAT fltVal; /* VT_R4 */
DOUBLE dblVal; /* VT_R8 */
VARIANT_BOOL boolVal; /* VT_BOOL */
_VARIANT_BOOL bool; /* (obsolete) */
SCODE scode; /* VT_ERROR */
CY cyVal; /* VT_CY */
DATE date; /* VT_DATE */
BSTR bstrVal; /* VT_BSTR */
IUnknown * punkVal; /* VT_UNKNOWN */
IDispatch * pdispVal; /* VT_DISPATCH */
SAFEARRAY * parray; /* VT_ARRAY */
BYTE * pbVal; /* VT_BYREF|VT_UI1 */
SHORT * piVal; /* VT_BYREF|VT_I2 */
LONG * plVal; /* VT_BYREF|VT_I4 */
FLOAT * pfltVal; /* VT_BYREF|VT_R4 */
DOUBLE * pdblVal; /* VT_BYREF|VT_R8 */
VARIANT_BOOL *pboolVal; /* VT_BYREF|VT_BOOL */
SCODE * pscode; /* VT_BYREF|VT_ERROR */
CY * pcyVal; /* VT_BYREF|VT_CY */
DATE * pdate; /* VT_BYREF|VT_DATE */
BSTR * pbstrVal; /* VT_BYREF|VT_BSTR */
IUnknown ** ppunkVal; /* VT_BYREF|VT_UNKNOWN */
IDispatch ** ppdispVal; /* VT_BYREF|VT_DISPATCH */
SAFEARRAY ** pparray; /* VT_BYREF|VT_ARRAY */
VARIANT * pvarVal; /* VT_BYREF|VT_VARIANT */
PVOID byref; /* Generic ByRef */
CHAR cVal; /* VT_I1 */
USHORT uiVal; /* VT_UI2 */
ULONG ulVal; /* VT_UI4 */
INT intVal; /* VT_INT */
UINT uintVal; /* VT_UINT */
DECIMAL * pdecVal; /* VT_BYREF|VT_DECIMAL */
CHAR * pcVal; /* VT_BYREF|VT_I1 */
USHORT * puiVal; /* VT_BYREF|VT_UI2 */
ULONG * pulVal; /* VT_BYREF|VT_UI4 */
INT * pintVal; /* VT_BYREF|VT_INT */
UINT * puintVal; /* VT_BYREF|VT_UINT */
} __VARIANT_NAME_3;
} __VARIANT_NAME_2;
DECIMAL decVal;
} __VARIANT_NAME_1;
};
OLE 자동화 변형 데이터 유형의 정의입니다.보다시피, 그것은 가능한 많은 종류가 다양합니다.원하는 클라이언트 코드의 기능에 따라 다양한 상황에서 사용할 수 있는 유형에 대한 많은 규칙이 있습니다.모든 유형이 모든 언어에서 지원되는 것은 아닙니다.
사용할 유형VT_BYREF
기본적으로 매개 변수를 기준으로 전달하는 VBScript와 같은 언어에서 사용됩니다.즉, 변형 구조 세부 정보(예: C++)가 VB와 같은 코드에 의해 호출되는 것에 관심이 있는 코드가 있는 경우, 필요한 경우 변형 매개 변수의 참조를 신중하게 취소해야 합니다.
기준 유형은 함수에서 값을 반환하는 데도 사용됩니다.이름이 이상하게 잘못 지정된 어레이 유형도 지원됩니다.SAFEARRAY
type - C++에서 사용하기가 너무 어렵습니다.
문자열 배열이 있는 경우 vbscript에 전달할 수 있지만 크기를 인쇄하는 경우를 제외하고는 사용할 수 없습니다.값을 실제로 읽으려면 어레이 데이터가 유형이어야 합니다.VT_BYREF | VT_BSTR
.
노조와의 "해크"는 휴대성 문제(엔디엔시, 정렬 문제)를 야기하지 않도록 하십시오.
유니언의 합법적인 사용은 서로 다른 데이터 유형을 동일한 위치에 저장하는 것입니다. 가급적이면 태그를 사용하여 유형을 알 수 있습니다.1800 INFORMATION의 예를 참조하십시오.
union을 사용하여 데이터 유형(예: 정수에서 수 바이트) 간에 변환하지 마십시오.휴대성을 위해 이동 및 마스킹을 대신 사용합니다.
우리는 직장에서 패킹된 메시지(C/C++)에 유니언을 사용하므로 유니언이 있는 구조물을 데이터 구성원으로 전달한 다음 구조물의 id 필드를 기반으로 올바른 경로에 액세스할 수 있습니다.
누군가가 구조물을 파일에 쓰기 전까지는 잘 작동했지만, 이제는 파일에 사용되는 최대 데이터로 제한됩니다. 파일 버전이 있음에도 불구하고 아무도 변경하지 않았기 때문입니다.
따라서 메모리 내 작업에 유용하지만 디스크나 네트워크에 맹목적으로 쓰는 것은 피해야 합니다.
우연히도, 저는 스택 오버플로 답변에서 6비트 필드로 구성된 단어를 두 개의 16비트 부호 없는 정수로 처리할 수 있도록 하나를 사용했습니다.
몇 년 전, 저는 (최초의) ARMC 컴파일러에도 하나를 사용했습니다. 당시의 명령어는 모두 32비트였지만 정확한 명령어에 따라 레이아웃이 다릅니다.그래서 저는 ARM 명령어를 표현하기 위해 조합을 만들었습니다. 각각 특정 명령어 유형에 적합한 비트 필드를 가진 일련의 구조를 포함합니다.
struct InputEvent
{
enum EventType
{
EventKeyPressed,
EventKeyPressRepeated,
EventKeyReleased,
EventMousePressed,
EventMouseMoved,
EventMouseReleased
} Type;
union
{
unsigned int KeyCode;
struct
{
int x;
int y;
unsigned int ButtonCode;
};
};
};
...
std::vector<InputEvent> InputQueue;
유니온 해킹으로 물체의 벡터를 간단하게 만들 수 있습니다.좀 더 깨끗하게 할 수 있을 거라 확신합니다하지만 저한테는 효과가 있어요 - 키스
#define DWORD unsigned int
#define WORD unsigned short
#define BYTE unsigned char
typedef union _DWORD_PART_ {
DWORD dwWord;
struct {
WORD dwMSB;
WORD dwLSB;
}hw;
struct {
BYTE byMSB;
BYTE byMSBL;
BYTE byLSBH;
BYTE byLSB;
} b;
} DWORD_PART;
이것은 단어 부분에 쉽게 접근할 수 있는 방법입니다. (한 번 완료하면 플랫폼의 엔디언 변경도 쉽게 처리할 수 있습니다.)
언급URL : https://stackoverflow.com/questions/724617/examples-of-union-in-c
'programing' 카테고리의 다른 글
도커 컨테이너에서 실행되는 Spring Boot 응용 프로그램의 상태를 확인하는 방법은 무엇입니까? (0) | 2023.08.04 |
---|---|
Spring Boot - 웹 서버가 시작될 때까지 대기 (0) | 2023.08.04 |
URL 매개 변수 값 가져오기 (0) | 2023.08.04 |
ECMA스크립트 6에는 추상 클래스에 대한 규약이 있습니까? (0) | 2023.08.04 |
mysqdump: 쓰기에서 오류 32를 받았습니다. (0) | 2023.08.04 |