2016-10-24 3 views
-2

임베디드 프로그래밍에서는 종종 하나의 공용체에 15 개의 struct를 넣는 경우가 있습니다. 그것은 일반적인 관행이며, RAM을 너무 작고 너무 소중하기 때문에 저를 포함하여 대부분의 사람들이 공간을 절약한다고 가정합니다. 하지만 이제는 다른 고려 사항이 있습니까? 예를 들어, 속도?공간을 절약 할 수있을뿐만 아니라 노동 조합을 사용하면 다른 이점도 있습니까?

알려 주시기 바랍니다. 여기

은 당신의 생각에 대한 예를 들어 음식의 :

typedef struct 
{ 
union 
{ 
    struct{ 
    ... 
    } stru1; 


    struct{ 
    ... 
    } stru2; 


    struct{ 
    ... 
    } stru3; 


    struct{ 
    ... 
    } stru4; 

} 
}main_packet 
+1

어떻게 당신이 공간을 절약 할 생각하십니까 :

노동 조합이 대신 포인터를 사용할 수 있습니다 다른 유형으로 생의 바이트를 해석하는 캐스트? 그것은 사양에 정의 된 완전히 다른 이유이며, 대부분의 자습서 나 책에 대한 설명이 있습니다. –

+1

'노조 '는 가장 큰 항목의 크기이므로 반대로 : 많은 공간을 낭비합니다. – LPs

답변

4

, 그건 변형를 생성하는 데 사용하는 "공간을 절약"하는 노동 조합을 사용하여, 일반적으로 나쁜 관행으로 간주됩니다 (예를 들어, MISRA 금지 -C) 그리고 내가 권하는 것은 아무것도 없다. 변형 유형의 존재는 거의 항상 나쁜 프로그램 설계의 징조입니다.

노동 조합의 가장 일반적인 목적은 한 조합원에 기록하고 다른 회원을 통해 데이터를 읽을 수 있다는 것을 의미을 말장난 유형, 그들을 사용하는 다른 것입니다. 이것은 C에서 잘 정의 된 동작이며 하드웨어 관련 프로그래밍을 할 때 매우 유용합니다.

는 예를 들어, 당신은 같은 것을 할 수 있습니다

typedef union 
{ 
    uint32_t u32; 
    uint8_t u8 [4]; 
} my32_t; 

my32_t my32; 
my32.u32 = 1; 

if(my32.u8[0] == 1) 
{ 
    puts("little endian"); 
} 
else 
{ 
    puts("big endian"); 
} 

노동 조합은 회피 the strict aliasing rules로 사용할 수 있습니다. 다음과 같은 코드가 정의되지 않은 동작이 호출 것 :

typedef union 
{ 
    uint32_t u32; 
    uint16_t u16; 
} something_t; 

something_t x; 
x.u32 = 1; 
uint16_t u16 = x.u16; 

이 6.5에 나와 엄격한 앨리어싱의 예외에 따라 잘 정의 된 동작입니다 :이 버그를 방지하기 위해

uint32_t u32 = 1; 
uint16_t u16 = *(uint16_t*)&u32; // bad, strict aliasing violation 

를 코드는 다음과 같이 다시 작성할 수 있습니다/7

  • 재귀 포함한 부재 (들 중 상기 하나의 유형, 0의 부재를 포함하는 전체 또는 조합 형subaggregate 포함되거나 조합)
+0

죄송합니다. 귀찮게하기 위해서. 당신의 마지막 예는 엔디안에 달렸지, 안 그래? 제 말은'u16'이'0' 일 수 있습니다. – LPs

+0

@LPs 그렇습니다. 따라서 대부분의 경우 교대를 통해 정수 유형의 특정 부분에 액세스하는 것이 더 좋습니다. 하지만 u16 청크로 u32를 읽으 려 할 때 실제 시나리오가 있다고 상상해보십시오. 예를 들어, 16 비트 만 프로그래밍 할 수있는 eeprom 드라이버를 작성한 것을 기억합니다. – Lundin

+0

네, 여러 번했는데,'uint16_t u16 [sizeof (uint32_t)/sizeof (uint16_t)];' – LPs

0

동적 메모리 할당 (의 malloc/무료) 오버랩하지 않는 데이터 구조 whoses 수명 동안 메모리를 재사용함으로써, 공간을 절약 할 수있는 일반적인 방법이다. 노동 조합은이 목적을 달성하기가 매우 유연하지 않고 유지하기가 어렵습니다. malloc/free의 시간 오버 헤드가 정말로 받아 들일 수없는 특별한 경우에만 사용해야합니다.

유니온은 또한 C++로 코딩 할 경우 클래스 계층 구조가되는 "기본"짐승을 제공하는 데 사용됩니다. 대신에 :

class A { ... }; 
class B : public A { ... }; 
class C : public A { ... }; 
class D : public A { ... }; 

당신이 쓰는 : 당신이 C에서 B, C, D.에 필요한 다른 동작을 얻기 위해 가상 함수를 사용하여 C++에서

struct H 
    { 
    struct A a; 
    enum { Really_B, Really_C, Really_D } really; 
    union 
     { 
     struct B b; 
     struct C c; 
     struct D d; 
     }; 
    }; 

, 당신은 더 적은 유지 보수 스위치 또는/경우를 사용 else if "파생 된 유형"식별자 필드 (이 경우 "정말로")를 사용하여 생성합니다.

typedef union 
    { 
    float fp; 
    struct 
     { 
     unsigned fraction : 23; 
     unsigned exponent : 8; 
     unsigned sign  : 1; 
     } 
    fld; 
    } 
Floating_point; 
관련 문제