Ostatnio trafiłem na przydatną konstrukcję: sizeof buffer (bez nawiasów!).
Dzięki temu dowiedziałem się, że operator sizeof ma tak naprawdę dwa zastosowania:
- sizeof(int) – zwróci rozmiar typu int w bajtach
- sizeof buffer – zwróci rozmiar tablicy w bajtach (pod warunkiem, że jest to tablica statyczna)
Przykład
int main() { const char *strings[] = {"ala", "ma", "kota"}; cout << sizeof strings; return 0; }
zwróci liczbę 12 (bajtów), czyli rozmiar trzech wskaźników *char. Zgodne to jest z prawdą – nasza tablica rzeczywiście zawiera trzy wskaźniki. Możemy stąd bardzo łatwo wyciągnąć ilość elementów tablicy – wystarczy podzielić przez rozmiar pojedynczego elementu!
Zastosowanie
Można sobie np. uprościć iterowanie po tablicy statycznej:
int main() { const char *strings[] = {"ala", "ma", "kota", "\n"}; for (int i = 0; i < sizeof strings / sizeof strings[0]; i++) cout << strings[i] << " "; return 0; }
W efekcie dostaniemy na konsolę:
ala ma kota Press Enter to continue!
Dzięki temu nie musimy deklarować stałej określającej rozmiar tablicy, np. NUM_STRINGS.
Podsumowanie
Na koniec powtarzam, że ta konstrukcja działa tylko dla tablic alokowanych statycznie. Dla tablicy dynamicznej, sizeof buffer zwróci to samo, co sizeof(buffer) – czyli rozmiar pojedynczego wskaźnika w bajtach.
July 5th, 2011 on 17:58
Korzystając z doświadczenia z kompilatorem GCC, mógłbym to wyjaśnić trochę inaczej ;-]
Operator sizeof zawsze zwraca wielkość typu, a w przypadku referencji, bądź zmiennej, wielkość typu na który wskazuje jej referencja.
Zmienna strings w pierszym przypadku ma typ
const char *strings[3]
jednak w przypadku przekazania jej przez wartość ulega ona automatycznej zamianie na typ
const char **strings
(ten sam typ to wyrażenie const char *strings[] )
Żeby zachować typ przy przekazaniu jej do funkcji należy zadeklarować funkcję jako przyjmującą referencję do tablicy:
size_t returnSize( const char* (&strings)[10] )
{
return sizeof strings / sizeof strings[0]; // tutaj będzie 10
}
Można to łatwo wykorzystać to napisania szablonu zwracającego długość:
template
size_t returnSize( Type (&strings)[size] )
{
return size;
}
Należy jeszcze pamiętać że istnieje typ tablic zmiennej długości alokowanych na stosie (C99 variable length array), dla których operator sizeof jest zmuszony podać wielkość zaalokowanych bajtów na stosie.
int size=10;
char const * array[size];
assert( sizeof array / sizeof array[0] == size );
Oczywiście dla tak zadeklarowanej zmiennej array, kompilator nie będzie w stanie dopasować parametrów szablonu returnSize;