>

구조에서 비트 배열을 얻을 수 있다면 숙고하고 있었고 (이를 배우는 방법,더 나은 해결책은 아닙니다을 찾고 있습니다)

예를 들어 설명하겠습니다. 그런 코드를 상상해보십시오 :

#include <stdio.h>
struct A
{
    unsigned int bit0:1;
    unsigned int bit1:1;
    unsigned int bit2:1;
    unsigned int bit3:1;
};
int main()
{
    struct A a = {1, 0, 1, 1};
    printf("%u\n", a.bit0);
    printf("%u\n", a.bit1);
    printf("%u\n", a.bit2);
    printf("%u\n", a.bit3);
    return 0;
}

이 코드에는 구조체에 4 개의 개별 비트가 포함되어 있습니다. 비트 조작 작업을 컴파일러에 맡기고 개별적으로 액세스 할 수 있습니다. 내가 궁금했던 것은 그러한 일이 가능한지 여부입니다.

#include <stdio.h>
typedef unsigned int bit:1;
struct B
{
    bit bits[4];
};
int main()
{
    struct B b = {{1, 0, 1, 1}};
    for (i = 0; i < 4; ++i)
        printf("%u\n", b.bits[i]);
    return 0;
}

bits 선언을 시도했습니다   struct B   unsigned int bits[4]:1 로  또는 unsigned int bits:1[4]  소용없는 유사한 것들. 내 최고의 추측은 typedef unsigned int bit:1; 에 있었다   bit 를 사용하십시오.  유형으로 아직 작동하지 않습니다.

제 질문은, 그런 일이 가능합니까? 그렇다면 어떻게? 그렇지 않다면 왜 안됩니까? 부호없는 1 비트 int는 유효한 유형이므로 왜 배열을 얻을 수 없어야합니까?

다시 말해, 나는 이것을 대체하고 싶지 않다. 나는 그런 일이 어떻게 가능한지 궁금하다.

P.S. 코드가 C로 작성되었지만 메소드가 두 언어 모두에 존재한다고 가정하기 때문에 C ++로 태그를 지정하고 있습니다. 라이브러리가 아닌 언어 구조를 사용하여 C ++ 관련 방법이 있다면 알고 싶습니다.

업데이트 : 비트 작업을 직접 수행 할 수 있다는 것을 완전히 알고 있습니다. 나는 과거에 그것을 천 번했습니다. 나는 대신 배열/벡터를 사용하고 비트 조작을하는 답변에 관심이 없다. 이 건설이 가능한지 아닌지 다른 대안이 아니라고 생각합니다.

업데이트 : 참을성이없는 사람에 대한 답변 (neagoegab 덕분에) :

대신

typedef unsigned int bit:1;

사용할 수 있습니다

typedef struct
{
    unsigned int value:1;
} bit;

#pragma pack 를 올바르게 사용하는


  • 답변 # 1

    가능한 것은 아님-이것은 불가능하다(여기)-불가능하지 않은

    이 작업을 시도 할 수는 있지만1 비트는 1 바이트에 저장됩니다

    #include <cstdint>
    #include <iostream>
    using namespace std;
    #pragma pack(push, 1)
    struct Bit
    {
        //one bit is stored in one BYTE
        uint8_t a_:1;
    };
    #pragma pack(pop, 1)
    typedef Bit bit;
    struct B
    {
        bit bits[4];
    };
    int main()
    {
        struct B b = {{0, 0, 1, 1}};
        for (int i = 0; i < 4; ++i)
            cout << b.bits[i] <<endl;
        cout<< sizeof(Bit) << endl;
        cout<< sizeof(B) << endl;
        return 0;
    }
    
    

    출력 :

    0 //bit[0] value
    0 //bit[1] value
    1 //bit[2] value
    1 //bit[3] value
    1 //sizeof(Bit), **one bit is stored in one byte!!!**
    4 //sizeof(B), ** 4 bytes, each bit is stored in one BYTE**
    
    

    한 바이트에서 개별 비트에 액세스하기위한 예는 다음과 같습니다.(비트 필드의 레이아웃은 구현에 따라 다릅니다)

    #include <iostream>
    #include <cstdint>
    using namespace std;
    #pragma pack(push, 1)
    struct Byte
    {
        Byte(uint8_t value):
            _value(value)
        {
        }
        union
        {
        uint8_t _value;
        struct {
            uint8_t _bit0:1;
            uint8_t _bit1:1;
            uint8_t _bit2:1;
            uint8_t _bit3:1;
            uint8_t _bit4:1;
            uint8_t _bit5:1;
            uint8_t _bit6:1;
            uint8_t _bit7:1;
            };
        };
    };
    #pragma pack(pop, 1)
    int main()
    {
        Byte myByte(8);
        cout << "Bit 0: " << (int)myByte._bit0 <<endl;
        cout << "Bit 1: " << (int)myByte._bit1 <<endl;
        cout << "Bit 2: " << (int)myByte._bit2 <<endl;
        cout << "Bit 3: " << (int)myByte._bit3 <<endl;
        cout << "Bit 4: " << (int)myByte._bit4 <<endl;
        cout << "Bit 5: " << (int)myByte._bit5 <<endl;
        cout << "Bit 6: " << (int)myByte._bit6 <<endl;
        cout << "Bit 7: " << (int)myByte._bit7 <<endl;
        if(myByte._bit3)
        {
            cout << "Bit 3 is on" << endl;
        }
    }
    
    

  • 답변 # 2

    C ++에서는 std::bitset<4> 를 사용합니다 . 저장을 위해 최소 개수의 단어를 사용하고 모든 마스크를 숨 깁니다. 많은 언어가 표준 라이브러리에 구현되어 있기 때문에 C ++ 라이브러리를 언어와 분리하는 것은 실제로 어렵습니다. C에는 이와 같은 단일 비트 배열을 만드는 직접적인 방법이 없으며 대신 4 비트의 요소 하나를 만들거나 수동으로 조작을 수행합니다.

    수정 :

    와이즈 비즈

    실제로 구조체/클래스 멤버를 만드는 컨텍스트 이외의 다른 곳에서는 1 비트 부호없는 형식을 사용할 수 없습니다. 이 시점에서 다른 유형과는 너무 다르므로 자동으로 따르지 않으므로 배열을 만들 수 있습니다.

  • 답변 # 3

    C ++은

    The 1 bit unsigned int is a valid type, so why shouldn't you be able to get an array of it?

    를 사용합니다.  또는 std::vector<bool> .

    C에서 std::bitset<N> 를 에뮬레이트  의미 론적으로 다음과 같은 구조체를 사용합니다.

    std::vector<bool>
    
    

    여기서 struct Bits { Word word[]; size_t word_count; };  너비는 CPU의 데이터 버스와 동일한 구현 정의 유형입니다. 와이즈 비즈 나중에 사용되는 것처럼 데이터 버스의 너비와 같습니다.

    예 : 와이즈 비즈   Word 입니다  32 비트 머신 용, wordsize  64 비트 시스템의 경우; 와이즈 비즈  32 비트 시스템의 경우 32, 64 비트 시스템의 경우 64입니다.

    기능/매크로를 사용하여 비트를 설정/삭제합니다.

    비트를 추출하려면 Word 를 사용하십시오. .

    비트를 설정하려면 uint32_fast_t 를 사용하십시오. .

    비트를 지우려면 uint64_fast_t 를 사용하십시오. .

    비트를 뒤집으려면 wordsize 를 사용하십시오. .

    GET_BIT(bits, bit) (((bits)->)word[(bit)/wordsize] & (1 << ((bit) % wordsize))) 에 따라 크기 조정 기능을 추가하려면 SET_BIT(bits, bit) (((bits)->)word[(bit)/wordsize] |= (1 << ((bit) % wordsize))) 를 호출하는 크기 조정 기능을 만듭니다.   CLEAR_BIT(bits, bit) (((bits)->)word[(bit)/wordsize] &= ~(1 << ((bit) % wordsize))) 에서  그리고 FLIP_BIT(bits, bit) (((bits)->)word[(bit)/wordsize] ^= (1 << ((bit) % wordsize))) 변경  따라서. 이에 대한 정확한 세부 사항은 문제로 남아 있습니다.

    비트 인덱스의 올바른 범위 검사에도 동일하게 적용됩니다.

  • 답변 # 4

    이것은 모욕적이고 확장에 의존하지만 ...

    std::vector<bool>
    
    

  • 답변 # 5

    정수 배열 (int 또는 long)을 사용하여 임의로 큰 비트 마스크를 만들 수도 있습니다. select () 시스템 호출은 fd_set 유형에이 접근법을 사용합니다. 각 비트는 번호가 매겨진 파일 디스크립터 (0..N)에 해당합니다. 매크로는 비트를 지우는 FD_CLR, 비트를 설정하는 FD_SET, 비트를 테스트하는 FD_ISSET, FD_SETSIZE는 총 비트 수입니다. 매크로는 배열에서 액세스 할 정수와 정수의 비트를 자동으로 알아냅니다. 유닉스에서는 "sys/select.h";Windows에서는 "winsock.h"에 있다고 생각합니다. FD 기술을 사용하여 비트 마스크에 대한 고유 한 정의를 만들 수 있습니다. C ++에서는 비트 마스크 객체를 만들고 [] 연산자를 오버로드하여 개별 비트에 액세스 할 수 있다고 가정합니다.

    realloc

  • 이전 c# - List ForEach ForEach 메소드에서 요소 값 변경
  • 다음 laravel - 피벗 테이블에없는 경우