Pointers and Arrays
Iată un secret: în C, tablourile și pointerii sunt strâns legați. Când folosești numele unui tablou de unul singur, el decade într-un pointer către primul element
#include <stdio.h>
int main(void) {
int numere[] = {10, 20, 30, 40, 50};
int *p = numere; // fara &: numere ESTE deja o adresa
printf("%d\n", *p); // 10, primul element
printf("%d\n", *(p + 1)); // 20, al doilea element
printf("%d\n", *(p + 2)); // 30, al treilea element
return 0;
}
numere este în esență un pointer către primul element. p + 1 nu adaugă 1 byte, ci se mută la următorul int (4 bytes înainte). Aceasta se numește aritmetică de pointeri, și C se ocupă automat de mărime în funcție de tip
Asta înseamnă că tablou[i] este doar zahăr sintactic pentru *(tablou + i). Sunt literalmente același lucru
#include <stdio.h>
int main(void) {
int numere[] = {10, 20, 30};
printf("%d\n", numere[1]); // 20
printf("%d\n", *(numere + 1)); // 20, acelasi lucru!
return 0;
}
De aceea indicii tablourilor încep de la 0 în C. Primul element este la offset-ul 0 de la început: *(tablou + 0) este *tablou este tablou[0]
Putem și parcurge un tablou cu un pointer
#include <stdio.h>
int main(void) {
int numere[] = {10, 20, 30, 40, 50};
int n = 5;
int *p = numere;
for (int i = 0; i < n; i++) {
printf("%d\n", *p);
p++; // mergi la urmatorul element
}
return 0;
}
p++ avansează pointerul cu un element (un int înainte). Este echivalent cu bucla clasică numere[i] dar îți arată ce se întâmplă sub capotă
Îți amintești când am spus că transmiterea unui tablou către o funcție face sizeof să nu mai funcționeze? Acum înțelegi de ce. Când scrii
void afiseaza(int tablou[]) { }
compilatorul vede de fapt
void afiseaza(int *tablou) { }
Tabloul decade într-un pointer. Funcția primește doar adresa primului element: nu are nicio idee cât de mare este tabloul. De aceea transmitem mereu mărimea ca parametru separat
Misiune: Sumatorul buffer-ului de bandă
Un buffer brut de memorie a fost citit de pe bandă magnetică: mai întâi mărimea lui, apoi valorile propriu-zise. Scrie o funcție care parcurge buffer-ul folosind aritmetica de pointeri și returnează suma tuturor valorilor.
- Citește un întreg n, apoi n numere întregi, într-un tablou numere
- Scrie o funcție suma_tablou care primește un pointer la int și o mărime, și returnează suma tuturor elementelor
- Folosește aritmetică de pointeri în interiorul funcției: accesează elementele cu *(ptr + i) în loc de ptr[i]
- În main, apelează suma_tablou și afișează rezultatul
Exemplu
Intrare
4
5 10 15 20
Ieșire
50
Exemplu
Intrare
3
1 2 3
Ieșire
6