2010-10-22 35 views
13

Tôi muốn lưu trữ các bit trong một mảng (như cấu trúc). Vì vậy, tôi có thể làm theo một trong hai phương pháp sau đâyTrường bit so với Bitset

số cách tiếp cận 1 (AN 1)

struct BIT 
{ 
    int data : 1 
}; 

int main() 
{ 
    BIT a[100]; 
    return 0; 
} 

số cách tiếp cận 2 (AN 2)

int main() 
{ 
    std::bitset<100> BITS; 
    return 0; 
} 

Tại sao một người nào đó muốn AN 2 trên AN 1?

+3

Để trích dẫn trang cplusplus.com về bitset, "Lớp này rất giống với một mảng bình thường, nhưng tối ưu hóa cho việc phân bổ không gian". Nếu int của bạn là 4 byte, một bitet sử dụng ít hơn 32 lần không gian. – AlcubierreDrive

+2

Cấu trúc của bạn 'BIT' sẽ được căn chỉnh sao cho (ít nhất) một byte. – Archie

+0

@Jon, đăng câu trả lời đó. (Đó là một điểm tốt.) –

Trả lời

15

Vì phương pháp tiếp cận nr. 2 thực sự sử dụng 100 bit lưu trữ, cộng với một số chi phí rất nhỏ (liên tục), trong khi nr. 1 thường sử dụng bốn byte dung lượng lưu trữ cho mỗi cấu trúc Bit. Nói chung, struct có kích thước tối thiểu một byte cho mỗi tiêu chuẩn C++.

#include <bitset> 
#include <iostream> 

struct Bit { int data : 1; }; 

int main() 
{ 
    Bit a[100]; 
    std::bitset<100> b; 
    std::cout << sizeof(a) << "\n"; 
    std::cout << sizeof(b) << "\n"; 
} 

in

400 
16 

Ngoài ra, kết thúc tốt đẹp bitset mảng bit của bạn trong một đại diện đối tượng tốt đẹp với nhiều hoạt động hữu ích.

+0

Làm thế nào để đầu ra của 'sizeof (b)' là 16? 100 bit có nghĩa là 100/8 byte. Tôi đang thiếu gì? – CLOWN

+1

Nó phải được "làm tròn" thành bội số của tám, vì byte là đơn vị lưu trữ nhỏ nhất có thể định địa chỉ trực tiếp. Hãy thử biên dịch với 128 bit trong tập, sau đó nó vẫn còn 16. 'bitet' sử dụng một số thủ thuật để giả vờ nó thực sự là địa chỉ bit .. –

+0

bình luận trước đó của tôi là một nửa bên phải. Nó được làm tròn lên đến bội số của 4 byte, bởi vì một đơn vị bốn byte là nhanh nhất để xử lý cho một máy tính 32-bit. Nhưng trong mọi trường hợp, một byte là đơn vị địa chỉ nhỏ nhất, do đó, ít nhất là 13 (100/8 = 12,5 và một nửa byte không phải là địa chỉ). Xin lỗi, chiều thứ sáu. –

0

Phương pháp tiếp cận số 1 rất có thể sẽ được biên dịch thành một mảng gồm các số nguyên 4 byte và một bit của mỗi số sẽ được sử dụng để lưu trữ dữ liệu của bạn. Về mặt lý thuyết, một trình biên dịch thông minh có thể tối ưu hóa điều này, nhưng tôi sẽ không dựa vào nó.

Có lý do nào bạn không muốn sử dụng std::bitset không?

0

Để báo giá cplusplus.com's page on bitset, "Lớp này rất giống với một mảng thông thường, nhưng tối ưu hóa cho phân bổ không gian". Nếu int của bạn là 4 byte, một bitet sử dụng ít hơn 32 lần không gian.

Ngay cả khi thực hiện bool bits[100], như sbi đã đề xuất, vẫn còn tệ hơn bitet, bởi vì hầu hết các lần triển khai có> = 1 byte bools.

Nếu vì lý do tò mò trí tuệ duy nhất, bạn muốn thực hiện bitset của riêng bạn, bạn có thể làm như vậy bằng mặt nạ bit:

typedef struct { 
    unsigned char bytes[100]; 
} MyBitset; 

bool getBit(MyBitset *bitset, int index) 
{ 
    int whichByte = index/8; 
    return bitset->bytes[whichByte] && (1 << (index = % 8)); 
} 

bool setBit(MyBitset *bitset, int index, bool newVal) 
{ 
    int whichByte = index/8; 

    if (newVal) 
    { 
    bitset->bytes[whichByte] |= (1 << (index = % 8)); 
    } 
    else 
    { 
    bitset->bytes[whichByte] &= ~(1 << (index = % 8)); 
    } 
} 

(Xin lỗi vì sử dụng một struct thay vì một lớp học bằng cách này. Tôi đang nghĩ thẳng vào C vì tôi đang ở giữa nhiệm vụ cấp thấp cho trường học. Rõ ràng là hai lợi ích to lớn của việc sử dụng một lớp là quá tải của nhà điều hành và khả năng có một mảng có kích thước thay đổi.)

+3

Trong C++ sự khác biệt duy nhất giữa một lớp và cấu trúc là các thành viên lớp là riêng tư theo mặc định và cấu trúc thành viên được công khai theo mặc định. – M2tM

5

Một lựa chọn tốt phụ thuộc vào cách bạn sẽ sử dụng các bit.

std::bitset<N> có kích thước cố định. Visual C++ 10.0 là wrt không phù hợp. để xây dựng; nói chung bạn phải cung cấp một cách giải quyết. Điều này, trớ trêu thay, do những gì Microsoft nghĩ là một sửa lỗi - họ đã giới thiệu một nhà xây dựng tham số int, như tôi nhớ lại.

std::vector<bool> được tối ưu hóa theo cùng một cách như std::bitset. Chi phí: lập chỉ mục không trực tiếp cung cấp tham chiếu (không có tham chiếu đến từng bit riêng lẻ trong C++), nhưng thay vào đó trả về đối tượng proxy - không phải là thông báo cho đến khi bạn cố gắng sử dụng nó làm tham chiếu. Ưu điểm: lưu trữ tối thiểu, và vector có thể được thay đổi kích thước theo yêu cầu.

Chỉ cần sử dụng ví dụ: unsigned cũng là một tùy chọn, nếu bạn đang đi để đối phó với một số lượng nhỏ bit (trong thực tế, 32 hoặc ít hơn, mặc dù bảo lãnh chính thức chỉ là 16 bit).

Cuối cùng, TẤT CẢ các định danh UPPERCASE là theo quy ước (ngoại trừ Microsoft) dành riêng cho các macro, để giảm khả năng xảy ra xung đột tên. Do đó, tốt nhất là không nên sử dụng TẤT CẢ định danh TẤT CẢ cho bất kỳ điều gì khác ngoài macro. Và luôn sử dụng TẤT CẢ định danh TẤT CẢ UPPERCASE cho macro (điều này cũng giúp dễ dàng nhận ra chúng hơn).

Cheers & h.,

Các vấn đề liên quan