programing

구조와 유니언의 차이점

newsource 2022. 7. 28. 23:56

구조와 유니언의 차이점

어떤 좋은 예가 있을까요?struct및 aunion기본적으로는 알고 있습니다.struct멤버의 모든 메모리를 사용합니다.union는 가장 큰 멤버메모리 공간을 사용합니다.OS 레벨의 다른 차이가 있습니까?

유니온에서는 한 요소만 사용해야 합니다. 왜냐하면 그것들은 모두 같은 장소에 저장되어 있기 때문입니다.이렇게 하면 여러 가지 유형 중 하나일 수 있는 것을 저장할 때 유용합니다.한편, 구조체는 각각의 요소에 대해 별도의 메모리 위치를 가지며, 한 번에 모든 요소를 사용할 수 있습니다.

구체적인 사용 예를 들자면, 조금 전에 Scheme interpreter를 작업하고 있었는데, 기본적으로 Scheme 데이터 유형을 C 데이터 유형에 오버레이하고 있었습니다.여기에는 값의 유형을 나타내는 열거형 및 값을 저장하기 위한 결합이 포함됩니다.

union foo {
  int a;   // can't use both a and b at once
  char b;
} foo;

struct bar {
  int a;   // can use both a and b simultaneously
  char b;
} bar;

union foo x;
x.a = 3; // OK
x.b = 'c'; // NO! this affects the value of x.a!

struct bar y;
y.a = 3; // OK
y.b = 'c'; // OK

edit: x.b를 'c'로 설정하면 x.a의 값이 'c'로 변경되므로 엄밀히 말하면 정의되어 있지 않습니다.대부분의 최신 머신에서 char는 1바이트이고 int는 4바이트이기 때문에 x.b의 값 'c'를 지정하면 x.a의 첫 번째 바이트에도 같은 값이 부여됩니다.

union foo x;
x.a = 3;
x.b = 'c';
printf("%i, %i\n", x.a, x.b);

인쇄하다

99, 99

두 값이 동일한 이유는 무엇입니까?왜냐하면 int 3의 마지막 3바이트는 모두 0이기 때문에 99로 읽힙니다.x.a에 더 큰 숫자를 입력하면 항상 이러한 경우가 아님을 알 수 있습니다.

union foo x;
x.a = 387439;
x.b = 'c';
printf("%i, %i\n", x.a, x.b);

인쇄하다

387427, 99

실제 메모리 값을 자세히 알아보려면 값을 16진수로 설정하고 인쇄합니다.

union foo x;
x.a = 0xDEADBEEF;
x.b = 0x22;
printf("%x, %x\n", x.a, x.b);

인쇄하다

deadbe22, 22

0x22가 0xEF의 어느 부분을 오버프로트하는지 명확하게 알 수 있습니다.

그렇지만

C에서는 int 내의 바이트 순서는 정의되어 있지 않습니다.이 프로그램은 Mac에서 0xEF를 0x22로 오버숏하지만 int를 구성하는 바이트 순서가 반대로 바뀌었기 때문에 대신 0xDE를 덮어쓰는 플랫폼이 있습니다.따라서 프로그램을 작성할 때 유니언의 특정 데이터를 덮어쓰는 동작에 의존해서는 안 됩니다.이것은 휴대성이 없기 때문입니다.

바이트 순서에 대한 자세한 내용은 endianness를 참조하십시오.

간단한 답변입니다.구조는 레코드 구조입니다.구조 내의 각 요소는 새로운 공간을 할당합니다.그래서, 이런 구조물이

struct foobarbazquux_t {
    int foo;
    long bar;
    double baz; 
    long double quux;
}

최소 할당(sizeof(int)+sizeof(long)+sizeof(double)+sizeof(long double))("아키텍처 얼라인먼트 제약으로 인해 컴파일러가 구조에 패드를 채우게 될 수 있기 때문에 적어도")

반면에,

union foobarbazquux_u {
    int foo;
    long bar;
    double baz; 
    long double quux;
}

는 1개의 메모리 청크를 할당하고 4개의 에일리어스를 부여합니다.그렇게sizeof(union foobarbazquux_u) ≥ max((sizeof(int),sizeof(long),sizeof(double),sizeof(long double))정렬을 위한 추가 가능성이 있습니다.

'구조'와 '조합'의 차이를 보여주는 좋은 예가 있나요?

가상 통신 프로토콜

struct packetheader {
   int sourceaddress;
   int destaddress;
   int messagetype;
   union request {
       char fourcc[4];
       int requestnumber;
   };
};

이 상상의 프로토콜에서는 "메시지 유형"에 기초하여 헤더 내의 다음 위치가 요청 번호 또는 4개의 문자 코드 중 하나일 뿐 둘 다일 수는 없다고 명시되어 있습니다.즉, 결합을 통해 동일한 저장 위치를 둘 이상의 데이터 유형을 나타낼 수 있으며, 한 번에 하나의 데이터 유형만 저장할 수 있습니다.

유니언은 시스템 프로그래밍 언어로서의 C의 전통을 기반으로 한 하위 수준의 세부 사항으로, 스토리지 위치가 "중복"되는 경우가 있습니다.데이터 구조가 한 번에 여러 유형 중 하나만 저장되는 경우 결합을 사용하여 메모리를 절약할 수 있습니다.

일반적으로 OS는 구조나 유니언에 대해 신경 쓰지 않습니다.이것들은 모두 단순히 메모리 블록에 불과합니다.구조는 여러 데이터 개체를 저장하는 메모리 블록으로, 이러한 개체가 겹치지 않습니다.유니언은 여러 데이터 객체를 저장하지만 이들 중 가장 큰 객체만을 저장하기 때문에 한 번에 하나의 데이터 객체만 저장할 수 있는 메모리 블록입니다.

A union는 몇 가지 시나리오에서 도움이 됩니다. union커널용 디바이스 드라이버 쓰기 등 매우 낮은 수준의 조작을 위한 도구가 될 수 있습니다.

그 예로는 해부를 들 수 있습니다.float사용으로 번호를 매기다unionstruct비트필드와 a를 사용하여float. 에 번호를 저장합니다.float나중에 특정 부분에 액세스 할 수 있습니다.float그것을 통해struct이 예에서는,union데이터를 보는 각도가 다를 때 사용합니다.

#include <stdio.h>                                                                                                                                       

union foo {
    struct float_guts {
        unsigned int fraction : 23;
        unsigned int exponent : 8;
        unsigned int sign     : 1;
    } fg;
    float f;
};

void print_float(float f) {
    union foo ff;
    ff.f = f;
    printf("%f: %d 0x%X 0x%X\n", f, ff.fg.sign, ff.fg.exponent, ff.fg.fraction);

}

int main(){
    print_float(0.15625);
    return 0;
}

Wikipedia의 단일 정밀도 설명을 보십시오.저는 예시와 매직넘버 0.15625를 사용했습니다.


union는 여러 대안을 가진 대수적 데이터 유형을 구현하는 데도 사용할 수 있습니다.저는 오설리번, 스튜어트, 괴젠의 "리얼 월드 해스켈" 책에서 그 예를 찾았습니다.차별 조합 섹션에서 확인하십시오.

건배!

독립 속성 그룹을 가진 것을 모델링해야 할 때 구조를 사용하는 것이 권장되며, 기업이 여러 형태를 가지고 있고 한 번에 하나의 형태로만 존재할 수 있는 경우에는 결합을 사용해야 한다.

적용 가능한 두 곳을 살펴봅시다.

자동차 값을 저장하고 업데이트해야 합니다.그러기 위해서는 모델, 주행거리, 가격, 연료 종류 등 자동차의 특성을 모두 기록해야 합니다.이러한 값은 항상 차 안에 존재하며 다른 값에 의존하지 않습니다.따라서 모든 속성을 저장할 뿐만 아니라 적절한 업데이트를 보장하는 데이터 유형이 필요합니다.이러한 유형의 작업은 구조를 사용하여 수행할 수 있습니다.

struct car{
    char model[];
    int mileage;
    int price;
    char fuel_type[];
};

조직은 결제 확인을 위해 다수의 고객으로부터 데이터를 수집해야 합니다.이제 데이터 무결성과 고객 보안을 위해 조직은 개인으로부터 최소한의 세부 정보를 얻도록 지시받았습니다.이러한 세부 정보는 귀하의 PAN 번호 또는 계정 번호 또는 유권자 ID일 수 있습니다.이러한 세부사항 중 하나를 수집해야 하고 동시에 메모리 효율도 높여야 하기 때문에 여기서 union을 사용할 수 있습니다.이것은 제공된 단일 값만 유지합니다.

union verification_details{
    char account_number[10];
    char PAN[10];
    char voter_id[10];
};

나는 그것을 잘 설명하는 다음 기사를 발견했다: 구조와 유니언의 차이

네, 구조와 유니언의 주요 차이점은 말씀하신 바와 같습니다.Struct는 해당 멤버의 모든 메모리를 사용하며, Union은 가장 큰 멤버 메모리 공간을 사용합니다.

그러나 모든 차이점은 메모리의 사용 필요성에 있습니다.유니언의 최선의 사용은 신호를 사용하는 unix 프로세스에서 확인할 수 있습니다.마치 프로세스가 한 번에 하나의 신호에만 작동할 수 있는 것처럼요.따라서 일반적인 선언은 다음과 같습니다.

union SIGSELECT
{
  SIGNAL_1 signal1;
  SIGNAL_2 signal2;
  .....
};

이 경우 프로세스에서는 모든 신호 중 가장 높은 메모리만 사용합니다.그러나 이 경우 구조를 사용하면 메모리 사용량이 모든 신호의 합계가 됩니다.차이가 많이 나죠

요약하자면, 한 번에 구성원 중 하나에 액세스하는 것을 알고 있는 경우 Union을 선택해야 합니다.

네가 가지고 있어, 그게 다야.하지만, 기본적으로, 조합이 무슨 의미가 있을까요?

다른 유형의 동일한 위치 컨텐츠를 넣을 수 있습니다.유니언에 저장되어 있는 것의 유형을 알아야 합니다(대부분은 유니언에 저장함).struct타입 태그가 붙어 있습니다...)

이게 왜 중요하죠?공간확충을 위해서가 아닙니다.네, 비트를 늘리거나 패딩을 할 수도 있지만, 더 이상 그게 요점이 아닙니다.

이것은 타입의 안전을 위해서, 일종의 「다이내믹 타이핑」을 가능하게 합니다.컴파일러는, 컨텐츠가 다른 의미를 가지고 있을 가능성이 있는 것과, 런타임에 컨텐츠의 해석 방법에 대한 정확한 의미를 알고 있습니다.다른 타입을 가리킬 수 있는 포인터가 있는 경우는, 반드시 유니언을 사용할 필요가 있습니다.그렇지 않으면 에일리어싱 문제로 인해 코드가 잘못될 수 있습니다(컴파일러는 자신에게 "오, 이 포인터만이 이 타입을 가리킬 수 있기 때문에, 그러한 액세스를 최적화할 수 있고, 나쁜 일이 발생할 수 있습니다."라고 말합니다).

질문에서 이미 언급했듯이, 두 가지 주요 차이점은union그리고.struct그것이다union구성원은 결합의 크기가 하나가 되도록 서로의 메모리를 오버레이합니다.struct멤버는 1개씩 배치됩니다(옵션의 패딩이 그 사이에 있습니다).또한 조합은 조합원을 모두 수용할 수 있을 정도로 크고 조합원 전체에 맞는 정렬을 갖추고 있다.예를 들어int저장할 수 있는 것은 2바이트 주소, 폭 2바이트, 저장 가능한 것은 4바이트 주소, 길이 4바이트뿐입니다.다음 조합

union test {
    int a;
    long b;
}; 

을 가질 수 있다sizeof4 및 정렬 요구 사항 4입니다.유니언과 구조물은 모두 마지막에 패딩을 가질 수 있지만 시작에는 패딩을 사용할 수 없습니다.구조물에 쓰기를 수행하면 기록된 구성원의 값만 변경됩니다.조합원에게 편지를 쓰면 다른 모든 조합원의 가치가 무효가 된다.이전에 써본 적이 없으면 액세스할 수 없습니다. 그렇지 않으면 동작이 정의되지 않습니다.GCC는 가장 최근에 조합원들에게 편지를 쓰지 않았더라도 조합원들로부터 실제로 읽을 수 있는 확장 기능을 제공합니다.운영체제의 경우 사용자 프로그램이 유니언에 쓰든 구조물에 쓰든 상관없습니다.이것은 실제로는 컴파일러의 문제일 뿐입니다.

유니언과 구조의 또 다른 중요한 특성은 포인터가 멤버의 유형을 가리킬있다는 것입니다.따라서 다음 사항이 유효합니다.

struct test {
    int a;
    double b;
} * some_test_pointer;

일부_test_model은 다음을 가리킬 수 있습니다.int*또는double*. 타입의 주소를 입력했을 경우test로.int*첫 번째 멤버를 가리킵니다.a,정말로.노조도 마찬가지다.따라서 결합은 항상 올바른 정렬을 가지므로 결합을 사용하여 유효한 유형을 지정할 수 있습니다.

union a {
    int a;
    double b;
};

이 조합은 실제로 int와 더블을 가리킬 수 있습니다.

union a * v = (union a*)some_int_pointer;
*some_int_pointer = 5;
v->a = 10;
return *some_int_pointer;    

는 C99 표준에 기재된 바와 같이 실제로 유효합니다.

오브젝트는 다음 중 하나의 유형의 lvalue 식을 통해서만 저장된 값에 액세스할 수 있어야 합니다.

  • 물체의 유효 형태와 양립
  • ...
  • 구성원 중 앞서 언급한 유형 중 하나를 포함하는 집합체 또는 결합형

컴파일러가 최적화되지 않습니다.v->a = 10;가치에 영향을 줄 수 있기 때문에*some_int_pointer(기능이 돌아오다)10대신5).

구조체는 구조체 내의 모든 요소의 총 크기를 할당합니다.

유니언은 가장 큰 구성원이 필요로 하는 만큼의 메모리만 할당합니다.

구조와 조합의 차이점은 무엇입니까?

즉답은 다음과 같습니다.메모리 할당에 의존합니다.설명:구조에서는 구조 내부의 모든 멤버에 대해 메모리 공간이 생성됩니다.결합 메모리 공간은 가장 큰 메모리 공간을 필요로 하는 멤버에 대해서만 생성됩니다.다음 코드를 고려합니다.

struct s_tag
{
   int a; 
   long int b;
} x;

union u_tag
{
   int a; 
   long int b;
} y;

여기 구조와 결합 내부에는 int와 long int 두 멤버가 있습니다.int의 메모리 용량은 4바이트, long int의 메모리 용량은 8비트 운영체제입니다.

따라서 structure 4+8=12바이트는 생성되고 union은 8바이트가 생성됩니다.

코드 예:

#include<stdio.h>
struct s_tag
{
  int a;
  long int b;
} x;
union u_tag
{
     int a;
     long int b;
} y;
int main()
{
    printf("Memory allocation for structure = %d", sizeof(x));
    printf("\nMemory allocation for union = %d", sizeof(y));
    return 0;
}

참조: http://www.codingpractise.com/home/c-programming/structure-and-union/

유니언은 아래에 나와 있는 바이트 순서 지정 함수를 작성할 때 편리합니다.구조로는 불가능해요

int main(int argc, char **argv) {
    union {
        short   s;
        char    c[sizeof(short)];
    } un;

    un.s = 0x0102;

    if (sizeof(short) == 2) {
        if (un.c[0] == 1 && un.c[1] == 2)
            printf("big-endian\n");
        else if (un.c[0] == 2 && un.c[1] == 1)
            printf("little-endian\n");
        else
            printf("unknown\n");
    } else
        printf("sizeof(short) = %d\n", sizeof(short));

    exit(0);
}
// Program from Unix Network Programming Vol. 1 by Stevens.

기술적으로 말하면 다음과 같습니다.

가정: 의자 = 메모리 블록, 사람 = 변수

구조 : 3명이면 그에 맞는 크기의 의자에 앉을 수 있습니다.

유니온 : 만약 3명이 앉을 수 있는 의자가 하나밖에 없다면, 모두 앉고 싶을 때 같은 의자를 사용해야 합니다.

엄밀히 말하면 다음과 같습니다.

아래에 언급된 프로그램은 구조와 결합에 대한 심층적인 이해를 제공합니다.

struct MAIN_STRUCT
{
UINT64 bufferaddr;   
union {
    UINT32 data;
    struct INNER_STRUCT{
        UINT16 length;  
        UINT8 cso;  
        UINT8 cmd;  
           } flags;
     } data1;
};

총 MAIN_STRUCT 크기 = bufferaddr의 sizeof(UINT64) + union의 sizeof(UNIT32) + 패딩의 경우 32비트(프로세서 아키텍처의 경우) = 128비트.구조상 모든 구성원은 메모리 블록을 연속적으로 획득합니다.

Union은 최대 크기 멤버의 메모리 블록 1개를 가져옵니다(여기서는 32비트).유니언 내부에 하나 더 있는 구조(INNER_STRUCT)의 구성원은 총 32비트(16+8+8) 크기의 메모리 블록을 가집니다.조합하여 INSER_STRUCT(32비트) 멤버 또는 데이터(32비트)에 액세스할 수 있습니다.

"union"과 "struct"는 C 언어의 구성체입니다.이들 사이의 "OS 레벨" 차이에 대해 말하는 것은 적절하지 않습니다.하나 또는 다른 키워드를 사용하면 다른 코드를 생성하는 컴파일러이기 때문입니다.

유니언의 사용은 전문화된 유형의 대화가 필요할 때 자주 사용됩니다.결합의 유용성에 대한 아이디어를 얻기 위해.c/c 표준 라이브러리는 파일에 짧은 정수를 쓰도록 특별히 설계된 함수를 정의하지 않습니다.fwrite()를 사용하면 간단한 조작에 과도한 오버헤드가 발생합니다.그러나 결합을 사용하면 짧은 정수의 이진수를 한 번에 1바이트씩 파일에 쓰는 함수를 쉽게 만들 수 있습니다.짧은 정수의 길이는 2바이트라고 생각합니다.

예:

#include<stdio.h>
union pw {
short int i;
char ch[2];
};
int putw(short int num, FILE *fp);
int main (void)
{
FILE *fp;
fp fopen("test.tmp", "wb ");
putw(1000, fp); /* write the value 1000 as an integer*/
fclose(fp);
return 0;
}
int putw(short int num, FILE *fp)
{
pw word;
word.i = num;
putc(word.c[0] , fp);
return putc(word.c[1] , fp);
}    

putw() i가 짧은 정수로 호출했지만 putc()와 fwrite를 사용할 수 있었습니다.하지만 저는 어떻게 조합이 사용될 수 있는지를 지배하기 위한 예를 보여주고 싶었습니다.

구조는 서로 다른 데이터 유형의 집합으로, 서로 다른 유형의 데이터가 존재할 수 있으며 각 데이터마다 고유한 메모리 블록을 갖습니다.

일반적으로 유니언은 변수 중 1개만 한 번에 사용하는 것이 확실하고 현재 메모리를 최대한 활용해야 할 때 사용합니다.왜냐하면 메모리 블록은 가장 큰 타입과 같기 때문입니다.

struct emp
{
    char x; //1 byte
    float y; //4 byte
} e;

얻을 수 있는 메모리의 합계: = > 5 바이트.

union emp
{
    char x; //1 byte
    float y; //4 byte
} e;

얻을 수 있는 메모리의 합계: 4 바이트.

유니언은 유니언의 반복과 같은 구조와는 다르다: 그것은 같은 기억을 재정의하는 반면, 구조는 겹치거나 재정의하지 않고 차례로 정의한다.

구조와 결합의 차이를 보여주는 좋은 예가 있나요?

임베디드 시스템 애플리케이션의 실제 예는 다음과 같습니다.사용만 합니다.union하지만 그것은 확실히 기능성을 보여준다.union.

I2C 통신 프로토콜 사용을 위한 쓰기 함수uniontype - 전달된 배열에서 데이터를 검색할 때 데이터 스토리지에 사용됩니다.

union data
{
    uint32_t packet;
    uint8_t  packetbyte[4];
} txdata;

포인터를 통해 쓰기 함수에 전달되는 배열은 1바이트 크기의 요소를 포함합니다.for루프 이 바이트들은 4단계에서 하나씩 추출되어 각각의 요소에 저장됩니다.txdata.packetbyte멤버입니다.

루프 종료 후txdata.packet4바이트의 데이터가 저장되어 있습니다.txdata통신 버스를 통해 데이터를 전송하는 마지막 단계로서txdata.packet는 32비트 버퍼에 쓰이며, 쓰기 후 쓰기 시퀀스를 시작합니다.다음으로 콘텐츠를 재설정합니다.txdata.packet = 0next for loop 실행을 시작하기 전.

이렇게 하면 I2C 마스터는 통과된 입력 데이터가 전송되고 쓰기 기능이 종료될 때까지 32비트 패킷을 재전송할 수 있습니다.

언급URL : https://stackoverflow.com/questions/346536/difference-between-a-structure-and-a-union