programing

C: 조합은 어디서 실질적으로 사용되고 있습니까?

shortcode 2023. 9. 20. 21:20
반응형

C: 조합은 어디서 실질적으로 사용되고 있습니까?

나는 유형의 정렬이 보장되는 union max_align의 예를 가지고 있습니다. 나는 내 친구를 설명하기 위해 union이 실질적으로 사용되는 훨씬 더 간단한 예를 찾고 있습니다.

저는 텍스트를 파싱할 때 주로 조합을 사용합니다.나는 다음과 같은 것을 사용합니다.

typedef enum DataType { INTEGER, FLOAT_POINT, STRING } DataType ;

typedef union DataValue
{
    int v_int;
    float v_float;
    char* v_string;
}DataValue;

typedef struct DataNode
{
    DataType type;
    DataValue value;
}DataNode;

void myfunct()
{
    long long temp;
    DataNode inputData;

    inputData.type= read_some_input(&temp);

    switch(inputData.type)
    {
        case INTEGER: inputData.value.v_int = (int)temp; break;
        case FLOAT_POINT: inputData.value.v_float = (float)temp; break;
        case STRING: inputData.value.v_string = (char*)temp; break;
    }
}

void printDataNode(DataNode* ptr)
{
   printf("I am a ");
   switch(ptr->type){
       case INTEGER: printf("Integer with value %d", ptr->value.v_int); break;
       case FLOAT_POINT: printf("Float with value %f", ptr->value.v_float); break;
       case STRING: printf("String with value %s", ptr->value.v_string); break;
   }
}

유니언이 어떻게 많이 사용되는지 확인하려면 flex/bison을 사용하여 코드를 확인합니다.예를 들어, 부목에는 TON의 조합이 포함되어 있습니다.

저는 일반적으로 데이터에 대한 다양한 보기를 원하는 조합을 사용해 왔습니다. 예를 들어 32비트 색상 값을 사용하여 32비트 값과 빨간색, 녹색, 파란색 및 알파 구성 요소를 모두 원하는 경우

struct rgba
{
  unsigned char r;
  unsigned char g;
  unsigned char b;
  unsigned char a;
};

union  
{
  unsigned int val;
  struct rgba components;
}colorval32;

NB 비트 마스킹 및 시프트를 통해 동일한 작업을 수행할 수도 있습니다.

#define GETR(val) ((val&0xFF000000) >> 24)

하지만 노조의 접근 방식이 더 우아하다고 생각합니다

해당 포트를 메모리에 매핑하여 레지스터 또는 I/O 포트를 바이트 단위뿐만 아니라 비트 단위로 액세스하려면 아래 예를 참조하십시오.

    typedef Union
{
  unsigned int a;
struct {
  unsigned bit0 : 1,
           bit1 : 1,
           bit2 : 1,
           bit3 : 1,
           bit4 : 1,
           bit5 : 1,
           bit6 : 1,
           bit7 : 1,
           bit8 : 1,
           bit9 : 1,
           bit10 : 1,
           bit11 : 1,
           bit12 : 1,
           bit13 : 1,
           bit14 : 1,
           bit15 : 1
} bits;
} IOREG;

# define PORTA (*(IOREG *) 0x3B)
...
unsigned int i = PORTA.a;//read bytewise
int j = PORTA.bits.bit0;//read bitwise
...
PORTA.bits.bit0 = 1;//write operation

에서,unions일반적으로 COM 개체 간에 데이터를 전달하는 하나의 표준 방식인 태그가 지정된 변형을 구현하는 데 사용됩니다.

는 은 입니다.uniontype은 두 개체 사이에 임의의 데이터를 전달하기 위한 단일 자연 인터페이스를 제공할 수 있습니다.일부 COM 개체는 다음 중 하나를 포함할 수 있는 변형(예: 유형 또는 )을 전달할 수 있습니다.double,float,int든 간에,

윈도우 C++ 코드에서 COM 객체를 다루어야 한다면 곳곳에서 변종을 볼 수 있을 것입니다.

struct cat_info
{
int legs;
int tailLen;
};

struct fish_info
{
bool hasSpikes;
};


union 
{
fish_info fish;
cat_info cat;
} animal_data;

struct animal
{
char* name;
int animal_type;
animal_data data;
};

조합은 다른 종류의 메시지가 있는 경우 유용하며, 이 경우에는 어떤 중간 수준에서도 정확한 유형을 알 필요가 없습니다.발신자와 수신자만 메시지 실제 메시지를 구문 분석하면 됩니다.다른 레벨은 크기와 발신자 및/또는 수신자 정보만 알면 됩니다.

SDL은 http://www.libsdl.org/cgi/docwiki.cgi/SDL_Event 이벤트를 표현하기 위해 연합을 사용합니다.

당신은 이런것을 의미합니까?

union {
   long long a;
   unsigned char b[sizeof(long long)];
} long_long_to_single_bytes;

추가됨:

저는 최근에 AIX 머신에서 64비트 머신 인디케이터를 바이트 배열로 변환하기 위해 이것을 사용했습니다.

std::string getHardwareUUID(void) {
#ifdef AIX
   struct xutsname m; // aix specific struct to hold the 64bit machine id
   unamex(&b);        // aix specific call to get the 64bit machine id
   long_long_to_single_bytes.a = m.longnid;
   return convertToHexString(long_long_to_single_bytes.b, sizeof(long long));
#else // Windows or Linux or Solaris or ...
   ... get a 6byte ethernet MAC address somehow and put it into mac_buf
   return convertToHexString(mac_buf, 6);
#endif

여기에 연합이 유용할 수 있는 또 다른 예가 있습니다.

(제 아이디어가 아니라 c++ 최적화에 대해 설명하는 문서에서 이 내용을 발견했습니다.)

시작은-

.... 예를 들어, 공간 절약을 위해 조합을 사용할 수도 있습니다.

첫째, 비조합 방식:

void F3(bool useInt) {
    if (y) {
        int a[1000];
        F1(a);  // call a function which expects an array of int as parameter
    }
    else {
        float b[1000];
        F2(b);  // call a function which expects an array of float as parameter
    }
}

여기서 a와 b의 라이브 범위가 겹치지 않기 때문에 동일한 메모리 영역을 사용할 수 있습니다.a와 b를 조합에 가입시키면 많은 CPU 캐시 공간을 절약할 수 있습니다.

void F3(bool useInt) {

    union {
        int a[1000];
        float b[1000];
    };

    if (y) {
        F1(a);  // call a function which expects an array of int as parameter
    }
    else {
        F2(b);  // call a function which expects an array of float as parameter
    }
}

조합을 사용하는 것은 물론 안전한 프로그래밍 방법은 아닙니다. a와 b의 사용이 겹치면 컴파일러로부터 경고를 받지 않기 때문입니다.캐시 공간을 많이 차지하는 큰 개체에 대해서만 이 메서드를 사용해야 합니다. ...

끝판왕의

이런 식으로 노조를 이용한 적이 있습니다.

//Define type of structure
typedef enum { ANALOG, BOOLEAN, UNKNOWN } typeValue_t;
//Define the union
typedef struct  {
  typeValue_t typeValue;
  /*On this structure you will access the correct type of
    data according to its type*/
  union {
    float ParamAnalog;
    char  ParamBool;
  };
} Value_t;

그러면 다양한 종류의 값을 가진 배열을 선언하여 데이터를 효율적으로 저장하고 다음과 같은 "폴리모르프" 작업을 수행할 수 있습니다.

 void printValue ( Value_t value ) {
    switch (value.typeValue) {
       case BOOL:
          printf("Bolean: %c\n", value.ParamBool?'T':'F');
          break;
       case ANALOG:
          printf("Analog: %f\n", value.ParamAnalog);
          break;
       case UNKNOWN:
          printf("Error, value UNKNOWN\n");
          break;
    }
 }
  • 특정 유형으로 강제해야 하는 직렬 데이터를 읽을 때.
  • 에서 의미 값을 반환할 때lex로.yacc. (yylval)
  • 폴리모픽 타입(polymorphic type)을 구현할 때, 특히 DSL 또는 일반 언어를 읽는 타입
  • 다른 종류를 취하도록 의도된 기능을 특별히 호출하는 디스패처를 구현할 때.

최근에 벡터프로그래밍에 사용되는 어떤 유니언을 본 것 같습니다.벡터 프로그래밍은 인텔 MMX 기술, GPU 하드웨어, IBM의 Cell Broadband Engine 등에 사용됩니다.

벡터는 128 비트 레지스터에 해당할 수 있습니다.SIMD 아키텍처에 매우 일반적으로 사용됩니다.하드웨어에 128비트 레지스터가 있으므로 레지스터/variable에 4개의 단일 정밀도 floating 포인트를 저장할 수 있습니다.벡터의 개별 요소를 구성하고 변환하고 추출하는 쉬운 방법은 결합을 사용하는 것입니다.

typedef union {
    vector4f vec; // processor-specific built-in type
    struct { // human-friendly access for transformations, etc
        float x;
        float y;
        float z;
        float w;
    };
    struct { // human-friendly access for color processing, lighting, etc
        float r;
        float g;
        float b;
        float a;
    };
    float arr[4]; // yet another convenience access
} Vector4f;

int main()
{
    Vector4f position, normal, color;
    // human-friendly access
    position.x = 12.3f;
    position.y = 2.f;
    position.z = 3.f;
    position.w = 1.f;

    // computer friendly access
    //some_processor_specific_operation(position.vec,normal.vec,color.vec);
    return 0;
}

PlayStation 3 멀티코어 프로그래밍 또는 그래픽 프로그래밍에서 길을 찾는다면 더 많은 것들을 직면할 가능성이 높습니다.

제가 파티에 좀 늦었다는 것은 알지만, 실질적인 예로.VariantVB스크립트의 데이터 타입은 다음과 같이 구현됩니다.Union. 다음 코드는 여기에 없는 기사에서 가져온 단순화된 예입니다.

struct tagVARIANT
{
    union 
    {
        VARTYPE vt;
        WORD wReserved1;
        WORD wReserved2;
        WORD wReserved3;
        union 
        {
            LONG lVal;
            BYTE bVal;
            SHORT iVal;
            FLOAT fltVal;
            DOUBLE dblVal;
            VARIANT_BOOL boolVal;
            DATE date;
            BSTR bstrVal;
            SAFEARRAY *parray;
            VARIANT *pvarVal;
        };
    };
};

(기사에 나와 있는 것처럼) 실제 구현은 oaidl.h C 헤더 파일에서 찾을 수 있습니다.

예:

서로 다른 소켓 유형을 사용하지만 참조할 일반적인 유형을 원할 경우.

또 다른 예는 주조 작업을 절약하는 것입니다.

typedef union {
  long int_v;
  float float_v;
} int_float;

void foo(float v) {
  int_float i;
  i.float_v = v;
  printf("sign=%d exp=%d fraction=%d", (i.int_v>>31)&1, ((i.int_v>>22)&0xff)-128, i.int_v&((1<<22)-1));
}

대신:

void foo(float v) {
  long i = *((long*)&v);
  printf("sign=%d exp=%d fraction=%d", (i>>31)&1, ((i>>22)&0xff)-128, i&((1<<22)-1));
}

편의상, 저는 같은 클래스를 사용하여 xyzw 값과 rgba 값을 저장할 수 있도록 유니언을 사용합니다.

#ifndef VERTEX4DH
    #define VERTEX4DH

    struct Vertex4d{

        union {
            double x;
            double r;
        };
        union {
            double y;
            double g;
        };
        union {
            double z;
            double b;
        };
        union {
            double w;
            double a;
        };

        Vertex4d(double x=0, double y=0,double z=0,double w=0) : x(x), y(y),z(z),w(w){}
    };

#endif

는 에서 수.<X11/Xlib.h>일부 . IP (BSD ) 에 것은 거의 .<netinet/ip.h>예를 들어).

일반적으로 프로토콜 구현은 유니온 컨스트럭트(union construct)를 사용합니다.

조합은 또한 몇몇 장소(예를 들어 부동 소수점 비교 알고리즘에 대한 일부 기술)에서 바람직한 유형의 펀닝(punning)을 수행할 때 유용할 수 있습니다.

언급URL : https://stackoverflow.com/questions/1951269/c-where-is-union-practically-used

반응형