De ce sizeof nu dă lungimea tabloului într-o funcție
Separă capacitatea unui tablou de dimensiunea unui pointer. Înțelege de ce parametrul a[] nu păstrează automat numărul elementelor primite.
În acest material
În locul unde ai declarat un tablou clasic, sizeof(a) descrie dimensiunea lui în octeți. Într-o funcție cu parametru scris int a[], același nume este tratat ca pointer către elemente. sizeof(a) din acea funcție nu mai măsoară tabloul original.
Octeți, capacitate și dimensiune logică
Pentru int a[100], capacitatea este de 100 de elemente. Dimensiunea în octeți depinde de cât ocupă un int. Dacă ai citit numai n=7 valori, dimensiunea logică a datelor este 7, chiar dacă tabloul rezervă loc pentru 100.
Expresia sizeof(a)/sizeof(a[0]) poate calcula capacitatea unui tablou real în domeniul în care tipul lui este încă tablou. Nu află câte valori utile ai citit și nu devine o metodă universală de măsurare a oricărei variabile numite a.
Parametrul nu transportă automat numărul elementelor
Un pointer spune unde începe o zonă, nu câte elemente valide ai voie să citești. La un parametru de forma int a[], dimensiunea logică trebuie transmisă separat, de exemplu printr-un parametru n. Funcția trebuie să respecte contractul indicilor 0..n-1.
Scrierea unei dimensiuni în parantezele parametrului nu face ca acel număr să fie verificat automat la fiecare apel în forma obișnuită de parametru tablou. Nu te baza pe aspectul declarației pentru protecția accesului. Validează dimensiunea acolo unde este stabilit contractul.
Un tablou cu capacitate 100 poate avea numai 7 elemente utile. Parametrul obișnuit int a[] devine pointer; funcția trebuie să primească separat dimensiunea logică.Mărește schema ↗
De ce vectorul se comportă diferit
Un obiect std::vector păstrează propria dimensiune și o oferă prin size(). Când funcția primește vectorul potrivit, poate afla numărul elementelor construite. Tot trebuie să distingi această dimensiune de capacity(), spațiul rezervat pentru creșteri viitoare.
Această diferență nu înseamnă că tabloul clasic este greșit. Pentru limite fixe, el poate fi o reprezentare clară. Important este ca interfața funcției să transmită explicit informațiile pe care reprezentarea nu le păstrează singură.
Verificare practică
Gândește două apeluri care trimit același tablou, dar cer prelucrarea a 3, respectiv 7 elemente. Adresa de început este aceeași; numai n diferențiază cerințele. Dacă funcția ignoră n și deduce o lungime din dimensiunea pointerului, ambele apeluri devin greșite.
Revezi parametrii și tablourile, dimensiunea logică și vector și iteratori.
Întrebări frecvente
De ce sizeof nu află lungimea unui tablou primit ca parametru?
Un parametru scris int a[] este ajustat la un pointer. În funcție, sizeof(a) măsoară pointerul, nu tabloul apelantului și nici numărul elementelor utile.
Cum transmit corect dimensiunea unui tablou clasic unei funcții?
Transmite separat dimensiunea logică n și folosește numai pozițiile 0..n-1. Capacitatea rezervată poate fi mai mare și nu trebuie confundată cu numărul valorilor citite.
Când funcționează sizeof(a)/sizeof(a[0])?
Când a desemnează efectiv tabloul, nu un parametru ajustat la pointer. Formula dă capacitatea în elemente, care poate diferi de dimensiunea logică a datelor.