2009-12-14 9 views
26

W C, mam tablicę kodowanym zdefiniowane następująco:Wynik "sizeof" na tablicy structs w C?

struct D 
{ 
    char *a; 
    char *b; 
    char *c; 
}; 

static struct D a[] = { 
    { 
     "1a", 
     "1b", 
     "1c" 
    }, 
    { 
     "2a", 
     "2b", 
     "2c" 
    } 
}; 

chciałbym określić liczbę elementów w tablicy, ale sizeof(a) zwraca błędny wynik: 48, a nie 2. Czy robię coś źle, czy jest sizeof po prostu niewiarygodne tutaj? Jeśli to ważne, kompiluję się z GCC 4.4.

+0

Zobacz http://stackoverflow.com/questions/1598773/is-there-a-standard-function-in-c-that-would-return-- length-of-an-array/1598827#1598827 dla odpowiedź, która zawiera kilka hacków, aby techniki zamieszczone poniżej były bezpieczniejsze. –

Odpowiedz

27
sizeof a/sizeof a[0]; 

To kompilacji czas na stałym poziomie, dzięki czemu można go używać do, na przykład, utworzyć kolejną tablicę:

#define N sizeof a/sizeof a[0] 
int n_a[N]; 
+0

W tym przypadku, jeśli sizeof (a) wynosi 48, sizeof (a [0]) == 24. To sprawia, że ​​każdy znak * zajmuje 8 bajtów. sizeof (char *) to prawdopodobnie 4 lub 8, w zależności od wersji 32-bit/64-bit, ale kompilatory będą wyrównywać do siebie elementy struktury, więc każdy element kończy się przyjmowaniem 8 bajtów. – jmanning2k

+1

Tak, ale fajne jest to, że podział podaje prawidłowy rozmiar, czy jest dopełnienie, czy nie, czy jakikolwiek rozmiar tej struktury. –

+0

#define nie powinien mieć średnika na końcu – Paamand

37

sizeof daje rozmiar w bajtach, a nie liczba elementów. Jak mówi Alok, aby uzyskać liczbę elementów, podziel rozmiar w bajtach tablicy przez rozmiar w bajtach jednego elementu. Prawidłowe C Idiom:

sizeof a/sizeof a[0] 
+7

+1 za udzielenie lepszego wyjaśnienia. –

+10

Alternatywną, po prostu idiomatyczną wersją jest 'sizeof a/sizeof * a' – caf

7

sizeof zwraca rozmiar pamięci przekazany elementu. Dzieląc rozmiar tablicy przez pojedynczy rozmiar elementu, otrzymujesz liczbę elementów.

Należy pamiętać, że rozmiar elementu może również zawierać niektóre bajty dopełnienia. Z tego powodu wyściełana struktura (np. Gdy element znaku jest poprzedzony wskaźnikiem) będzie miał wartość sizeof większą niż suma rozmiaru członków.

Z drugiej strony nie zawracaj sobie głowy liczeniem elementów w tablicy: sizeof(a)/sizeof(a[0]) nadal będzie działać tak gładko, jak oczekiwano.