2009-09-27 3 views
0
union LowLevelNumber 
{ 
unsigned int n; 
struct 
{ 
    unsigned int lowByte : 8; 
    unsigned int highByte : 8; 
    unsigned int upperLowByte : 8; 
    unsigned int upperHighByte : 8; 
} bytes; 
struct 
{ 
    unsigned int lowWord : 16; 
    unsigned int highWord : 16; 
} words;  
}; 

이 공용체를 사용하면 부호없는 정수 바이트 또는 워드 단위로 액세스 할 수 있습니다. 그러나 코드는 오히려 추한 외모 :부호없는 정수의 바이트/단어에 액세스하는 C++ 클래스

var.words.lowWord = 0x66; 

나 같은 코드 작성할 수 있도록 해주는 방법이있다 :

var.lowWord = 0x66; 

업데이트 :
이 짧은 작성에 대한 정말/아름다운 코드 위의 예와 같습니다. 노조 솔루션 자체가 작동하지만, lowWord 또는 lowByte에 액세스 할 때마다 .words 또는 .bytes를 쓰고 싶지 않습니다.

+0

구현 정의 동작 인 w.r.t. union에서 비트 필드의 순서와 정수의 표현. 엔디안이 변경되면 중단되며, 다른 컴파일러간에 변경 될 수도 있습니다. C99 초안 6.7.2.1 # 9 및 6.5.2.3 # 5를 참조하십시오. – starblue

답변

6
union LowLevelNumber { 
    unsigned int n; 
    struct { 
     unsigned int lowByte : 8; 
     unsigned int highByte : 8; 
     unsigned int upperLowByte : 8; 
     unsigned int upperHighByte : 8; 
    }; 
    struct { 
     unsigned int lowWord : 16; 
     unsigned int highWord : 16; 
    }; 
}; 

참고 제거 byteswords 이름.

+0

그것으로 쉽습니다 - 고마워요 :) – SDD

+0

당신은 오신 것을 환영합니다. 그것은 내가 속성 에뮬레이션 접근법을 신경 쓰지는 않지만, 당신이 물어 본 질문과 당신이 주어진 답을 생각해 볼 때 당신이 떨어질 것이라고 기대하지 않았습니다. ;-) 이 나는 ​​느낌을 누군가가 올 것이다 가지고 대신 ;-) –

+0

내가 대신 자바를 사용한다고 생각 자바를 사용하는 것이 좋습니다. –

0

클래스에서 쉽게 래핑하고 get/set 접근자를 사용할 수 있습니다.

+0

이렇게하면 코드가 똑같이 "부풀어 오르게"되고 유니온을 사용하는 것보다 낫지 않다. – SDD

+0

인터페이스를 깨지 않으면 서 실제로 이식성있는 것을 구현할 수 있으며, 어떻게 더 부 풀릴 지 알지 못한다. – jalf

+0

내 질문에 설명 된 의미에서 부풀어 오르고 : 나는 접근 자 (.words,이 경우에는 .bytes) – SDD

2

C++

http://www.cplusplus.com/reference/stl/bitset/ 당신의 필요를 위해 봉사 할 것입니다 ?

일반 C 버전은 다음과 같이 보일 것입니다 : 이것은 아마 사용자 정의 클래스/노동 조합을 작성하는 것보다 도로 아래로 더 유지 관리가 될 것입니다

int32 foo; 

//... 

//Set to 0x66 at the low byte 
foo &= 0xffffff00; 
foo |= 0x66; 

, 그것은 전형적인 C 관용구를 다음 때문이다.

+0

나는 벌어지고있는 세계에서 궁금 그의 머리를 긁지 않을 것이다 표시되지 않습니다 , 그리고 노조 코드를 찾아야합니다 ... 오 ... 그리고 64 비트 컴퓨터에서도 코드가 잔인하게 실패 할 수 있습니다. – SDD

+0

위의 노동 조합에 대한 개선이 다음 사람 (2 년을 이상) 코드를 읽을 수 있기 때문에 그것은 개선의 이유 –

+0

심지어 foo.LowByte = 0x66이 코드보다 읽기 쉽다고 말하고 싶습니다. 컴파일러 모델이 LLP가 아니면 64 비트 시스템에서만 실패합니다. – SDD

2

당신은

short& loword() { return (short&)(*(void*)&m_source); } 

을하고 괄호를 상관하지 않는 경우 사용할 수 있습니다.

아니면 공상

public class lowordaccess 
{ 
    unsigned int m_source; 
public: 
    void assign(unsigned int& source) { m_source = source; } 
    short& operator=(short& value) { ... set m_source } 
    operator short() { return m_source & 0xFF; } 
} 

다음

struct LowLevelNumber 
{ 
    LowLevelNumber() { loword.assign(number); } 

    unsigned int number; 
    lowordaccess loword; 
} 
var.loword = 1; 
short n = var.loword; 

후자의 방법을 갈 수는 C++에서 알려진 속성 에뮬레이션입니다.

+0

난 정말 당신의 접근 방식을 좋아해요! 아주 좋은 – SDD

+0

나는이 감사하고, 내가 제시 코드 종류의 멋진 다른 상황에서 유용 할 수 있습니다, 정말 그것을 테스트하지 않았고, 나는 개인적으로 해커의 접근 방식은 훨씬 더 간단이라고 생각하고 더 잘 맞는 동안 매우 문제. – queen3

+0

그리고 내 코드처럼, 거기 문제 등 – queen3

0

이 조합을 사용하는 것은 좋지 않습니다. 휴대용이 아니기 때문입니다. 엔디 언.

접근 자 함수를 사용하고 비트 마스크와 교대로 구현합니다.

+0

사실이지만 두 가지 유형의 엔디안 모두에서 작동 할 수있는 클래스를 어떻게 작성 하시겠습니까? – SDD

+0

비트 마스크와 시프트로 구현하십시오. 이는 엔디안과는 독립적으로 작동합니다. – starblue

+0

네,하지만 큰/작은 엔디안을 구별하기 위해서는 여전히 #define이 필요합니다. 노조와 함께 할 수없는 이유를 모르겠습니다. – SDD

관련 문제