2011-12-19 15 views
53
struct _USBCHECK_FLAGS 
    { 
     unsigned char DEVICE_DEFAULT_STATE  : 1; 
     unsigned char DEVICE_ADDRESS_STATE  : 1; 
     unsigned char DEVICE_CONFIGURATION_STATE : 1; 
     unsigned char DEVICE_INTERFACE_STATE  : 1; 
     unsigned char FOUR_RESERVED_BITS   : 8; 
     unsigned char RESET_BITS     : 8; 
    } State_bits; 

Co oznacza :1 i :8?":" (dwukropek) w strukturze C - co to znaczy?

+6

[bitfields w C] (http://en.wikipedia.org/wiki/C_syntax#Bit_fields). – birryree

+0

Zobacz http://pl.wikipedia.org/wiki/Bit_field dla przykładów –

+47

"FOUR_RESERVED_BITS: 8" ... – RJFalconer

Odpowiedz

46

te są Pola bitów. Zasadniczo liczba po dwukropku opisuje ile bitów wykorzystuje to pole. Oto quote from MSDN opisujące pola bitów:

Wyrażenie stałe określa szerokość pola w bitach. Specyfikator typu dla deklaratora musi być bez znaku int, int lub int, a wyrażenie stałe musi być nieujemną liczbą całkowitą. Jeśli wartość wynosi zero, deklaracja nie ma deklaratora. Tablice bitów pola, wskaźniki do pól bitów i funkcje zwracające pola bitów są niedozwolone . Opcjonalny deklarator nazywa pole bitowe. Pola bitowe mogą być zadeklarowane tylko jako część struktury. Adres operatora (&) nie może być zastosowany do komponentów pola bitowego.

Nienazwanych pól bitów nie można odwoływać się, a ich zawartość w czasie wykonywania jest nieprzewidywalna. Mogą być używane jako pola "obojętne" do celów wyrównania. Nienazwane pole bitowe, którego szerokość jest określona jako 0 , gwarantuje, że pamięć dla elementu następującego po nim na liście deklaracji strukturalnych rozpoczyna się na granicy wewnętrznej.

Ten przykład definiuje dwuwymiarową tablicę struktur o nazwie screen.

struct 
{ 
    unsigned short icon : 8; 
    unsigned short color : 4; 
    unsigned short underline : 1; 
    unsigned short blink : 1; 
} screen[25][80]; 

Edit: kolejny ważny nieco z linku MSDN:

pól bitowych mają takie same semantykę jako typ całkowitej. Oznacza to, że pole bitowe jest używane w wyrażeniach w dokładnie taki sam sposób, jak użyto zmiennej tego samego typu bazy, niezależnie od tego, ile bitów wynosi w polu bitowym.

Szybka próba ilustruje to ładnie. Co ciekawe, w przypadku typów mieszanych kompilator domyślnie przyjmuje wartość sizeof (int).

struct 
    { 
    int a : 4; 
    int b : 13; 
    int c : 1; 
    } test1; 

    struct 
    { 
    short a : 4; 
    short b : 3; 
    } test2; 

    struct 
    { 
    char a : 4; 
    char b : 3; 
    } test3; 

    struct 
    { 
    char a : 4; 
    short b : 3; 
    } test4; 

    printf("test1: %d\ntest2: %d\ntest3: %d\ntest4: %d\n", sizeof(test1), sizeof(test2), sizeof(test3), sizeof(test4)); 

1 Test: 4

test2 2

test3 1

test4: 4

+0

Link jest przestarzały, proszę go zaktualizować. – zhangxaochen

+0

Zaktualizowany nowym łączem MSDN i tekstem na wypadek, gdyby link zniknął. – JoeFish

+0

Nadal go nie rozumiem. Czy to oznacza, że ​​C++ automatycznie scala twoje "zmienne" w rozmiar int, tak że używane są wszystkie bity? Czy potrafisz rzucić nieco struktury pola na liczby, aby uzyskać typowe "* int with flags *". –

6

Definiuje bitowych pól o szerokości 1 do 8.

+19

Podczas gdy dokładne, odpowiedź powinna wyjaśnić, co bitfield _is_. –

4

również prowadził do zapisu jelit, ale w swoim kontekście pola bitowe nie miały sensu. Więc trochę kopałem. Ta notacja jest również używana do przypisywania wartości - w mojej konkretnej sytuacji wskazuje wskaźniki do funkcji.

Źródło: http://www.tldp.org/LDP/lkmpg/2.4/html/c577.htm

Poniżej znajduje się przykładowy i fragment wyjaśnić.

"Istnieje rozszerzenie gcc, które sprawia, że ​​przypisywanie do tej struktury jest bardziej wygodne. Zobaczycie ją w nowoczesnych sterownikach i może was zaskoczyć, tak wygląda nowy sposób przyporządkowania do struktury ”

struct file_operations fops = { 
    read: device_read, 
    write: device_write, 
    open: device_open, 
    release: device_release 
}; 

C99 (stare, kompatybilne) droga wygląda następująco:

struct file_operations fops = { 
    .read = device_read, 
    .write = device_write, 
    .open = device_open, 
    .release = device_release 
}; 
+0

Widziałem to również! Zawsze myślałem, że rozszerzenie gcc było '.x = y' i standard go zaadaptował, aż później zobaczyłem notację' x: y'. Wydaje mi się, że standardowy wygląda lepiej. – Shahbaz

+6

Po pierwsze, nie jest to przypisanie, jest to * inicjalizacja *. Po drugie, funkcja, którą opisujesz (* wyznaczone inicjatory *), nie ma absolutnie nic wspólnego z pytaniem (* pola bitowe *). Tylko dlatego, że przestarzałe rozszerzenie GCC używało ':' w składni, nie oznacza, że ​​jest w jakikolwiek sposób związane z ':' w pytaniu. – AnT

+4

AnT, ktoś szukający "dwukropka inicjalizacji struktury C" może znaleźć tę odpowiedź i właśnie tego szukałem. Dzięki, user27346! – ChrisPhoenix