programing

C에서의 유니온의 예

abcjava 2023. 8. 4. 22:34
반응형

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에서 .structC++에서 당신은 다음과 같이 할 수 있습니다.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와 같은 코드에 의해 호출되는 것에 관심이 있는 코드가 있는 경우, 필요한 경우 변형 매개 변수의 참조를 신중하게 취소해야 합니다.

기준 유형은 함수에서 값을 반환하는 데도 사용됩니다.이름이 이상하게 잘못 지정된 어레이 유형도 지원됩니다.SAFEARRAYtype - 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

반응형