* Защо първият елемент на масив е с индекс 0?
Публикувано на 12 февруари 2026 в раздел С/С++.
Когато обясняваме за масиви и адресиране на елементите им, трябва да накараме учениците да осъзнаят, че използването на името на променливата е всъщност препратка към адреса на първия елемент на масива. Обясняваме им, че обръщането към arr[2] реално извършва чисто математическа операция, която е *(arr+2). Първото, с което обикновено се започва, е демонстрирането на това какво всъщност съдържа променливата arr:
int arr[3];
printf("%d\n", arr);
Вижда се някакво голямо число - именно това е адреса на първия елемент на масива в паметта. Тогава какво става ако прибавим единица към това число? Досетихте се - преминава се към следващия елемент. Това може да се покаже чрез следния пример. Макар всички тези „гимнастики“ в кода да са много лоша практика, идеята тук не е да се пише код по този начин, а да се осъзнае математиката зад кода:
int arr[4];
arr[0] = 1;
*(arr + 1) = 5; // същото като arr[1] = 5
*(2 + arr) = 6; // събирането е комутативна операция
3[arr]=9; // същото като *(3 + arr) = 9
arr[1]++;
2[arr]++; // същото
printf("%d\n", arr[1]);
printf("%d", *(arr + 2));
return 0;
От този примери се вижда веднага, че arr[2], *(arr+2), *(2+arr) и съответно 2[arr] са едно и също нещо - те дават просто математическа сметка. И точно оттук идва и причината първият елемент на масив да е с индекс 0, а не 1. Ако беше 1, трябваше винаги да вадим една единица в сметката, а оттам има една математическа операция в повече. Хората, които са създали езика, са решили, че е по-добре тази операция да бъде спестена. За сметка на това програмистите е трябвало да свикнат, че адресацията на елементи започва от 0.
Със сигурност след тази демонстрация не използвайте никога алтернативните изписвания. В частност замяната на arr[i][j] с i[arr][j], j[i][arr] или i[j][arr] е категорично абсурдно.
Тук е момента да обясним един специфичен детайл - има разлика между arr и &arr. Макар и първоначално да изглежда все едно те съдържат едно и също нещо (следния код ще отпечата един и същи адрес):
int arr[3];
printf("%d\n", arr);
printf("%d\n", &arr);
има една съществена разлика - arr в случая е от тип int, докато &arr е от тип int[3]. Това може да се демонстрира лесно чрез следния код:
printf("%d\n", arr+1);
printf("%d\n", &arr+1);
Първият ред ще отпечата адреса на втория елемент на масива, докато втория ред ще отпечата един елемент след края на масива.
Добави коментар